2017-01-05 2 views
0

Я использую TransactionScope, так что я могу быть уверен, что либо все мои данные удалены & сохранено, либо все откат.C# TransactionScope - Заблокировать записи Проблема

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

Вот код: -

using (var scope = new TransactionScope()) 
{ 
     using (var ctx = new ApplicationDbContext(schemaName)) 
     { 
     // Delete 
     foreach (var item in queries) 
     { 
      // Delete queries - more than 30 queries - optimized already 
      ctx.Database.ExecuteSqlCommand(item);     
     } 

     // Bulk Insert 
     BulkInsert(ConnectionString, "Entry", "Entry", bulkTOEntry); 
     BulkInsert(ConnectionString, "WrongEntry", "WrongEntry", bulkWrongEntry); 
     } 
     scope.Complete();   
} 

Цикл foreach для операции удаления занимает слишком много времени & вызывает блокировку на записи. Если я возьму этот код из TransactionScope, тогда у меня не будет возможности отката.

Каков выход из этого? Есть ли другой способ ускорить удаление чем-то вроде Bulk Deletes?

- Добавлена ​​

DELETE FROM [Entry] 
WHERE CompanyId = 1 
    AND EmployeeId IN (3, 4, 6, 7, 14, 17, 20, 21, 22,....100 more) 
    AND Entry_Date = '2016-12-01' 
    AND Entry_Method = 'I' 

Сотрудники Идентификаторы различны для разных Entry_date.

план выполнения запроса: -

enter image description here

+0

Используйте хранимые процедуры. К сожалению, транзакции применимы только для коротких операций. – buffjape

+1

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

+0

Когда вы говорите «слишком много времени», что ** точно ** вы имеете в виду? Мы говорим миллисекунды? секунд? минут? часы? И «более 30», сколько в данном сценарии? 35? 350? 3500? 3,5 миллиона? –

ответ

1

TransactionScope по умолчанию Serializable уровня изоляции. Это самый безопасный уровень, но и наименее одновременный. Вы часто хотите явно установить более общий уровень изоляции:

using (var scope = new TransactionScope(
      TransactionScopeOption.Required, 
      new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted })) 
{ 
    ... 
} 
+0

Спасибо за ответ, я попробую эту штуку. – Anup

1

У вас есть правильные установки индексов? Я бы рекомендовал вам извлечь план выполнения для одного из ваших запросов на удаление и проверить, что стоит больше всего.

И если возможно, добавьте индекс, чтобы исправить проблему!

+0

У меня уже есть указатель на EmployeeId & Entry_Date, более того, если я удалю эти запросы непосредственно на SQL Server, это также требует времени. Проблема здесь в том, что Locking & Rolling Back. – Anup

+0

@ Да, я понимаю, что запрос требует времени независимо от того, где вы его выполняете, но с некоторой удачей вы можете заставить его работать быстрее, глядя на план выполнения и выясняя, что делает его настолько медленным. – Peter

+0

Спасибо за предложение, i просто удалось запустить мой 1 запрос на удаление и приложил образ плана выполнения. Пожалуйста, направляйте меня, поскольку я не очень хорошо знаю индексы.! – Anup