SqlBulkCopy вставляет, когда внутри транзакции предотвращается любая другая запись на таблицу

asp.net c# sql sqlbulkcopy sql-server

Вопрос

В моем веб-приложении пользователи могут вставлять сразу несколько данных, чтобы повысить производительность. Я использую класс SqlBulkCopy. Он выполняется несколько раз для одной операции, вставляемой в две разные таблицы. Если пользователь отменяет операцию или она терпит неудачу, мне нужны данные для отката, поэтому я переношу все в транзакцию с использованием моментального снимка уровня изоляции.

Насколько я понимаю, использование изоляции Snapshot позволило бы другим пользователям одновременно писать и читать таблицы. Однако, пока происходит одна загрузка данных, он блокирует любые другие записи в таблице до завершения всей родительской транзакции.

Вот несколько упрощенных кодов, которые показывают проблему. Я исключаю много функций, но идея остается прежней. Я перебираю некоторое количество из памяти в памяти, перетаскиваю их в таблицу, откладываю назад, а массовую копию в другую таблицу.

using (var transaction = myDbContext.Database.BeginTransaction(
System.Data.IsolationLevel.Snapshot))
 {
   var myCollectionOfObjects;

   while(!GetData(ref myCollectionOfObjects))  
   {     

    SqlBulkCopy bulkCopy = new SqlBulkCopy(myCon, transaction);

    //Sets the columns + rows
    SetUp(bulkCopy);

    bulkCopy.WriteToServer();
    //After the bulkcopy operation is complete
    // we retrieve the rows inserted and do another bulk copy to a different table

    var recentlyAddedRows = GetRecentlyAddedRow();

    SqlBulkCopy otherTableBulkCopy = new SqlBulkCopy(myCon, transaction);


    SetUpBulkCopyForOtherTable(otherTableBulkCopy);

    otherTableBulkCopy.WriteToServer();         
     }
    transaction.Commit();
 }

Поэтому, если один пользователь в данный момент находится внутри этой транзакции, даже если он откатывается, все остальные транзакции записи в таблицу будут заблокированы, так что другие пользователи, выполняющие одну и ту же функцию или пытающиеся записать в таблицу, будут заблокированы.

Это ожидаемое поведение и есть ли способ обойти это?

редактировать

Если посмотреть на блокировки, применяемые в SQL, это, по-видимому, связано с классом объемной копии, в результате чего на объект таблицы устанавливается исключительная блокировка (X), где, как если бы вы вставляли их по одному, применяется только блокировка намерения на столе (IX). Все еще не уверен, есть ли способ обойти это, но я предполагаю, что это связано с эскалацией блокировки.

Изменение блокировки страницы «Разрешить» в индексах таблиц и изменение размеров партии массовых копий в некоторых моих тестах полностью блокировалось, но они темпераментны.

Популярные ответы

IsolationLevel относится только к чтению, а не к записи. Если один из ваших клиентов пишет данные, другой клиент должен иметь возможность читать данные так, как это было до начала транзакции, однако он не сможет писать одновременно.



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему