2017-01-05 33 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中取出代码,那么我将无法回滚。

这是什么方法?有没有其他方法可以加快通过类似批量删除的删除操作?

- 增加

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' 

员工ID是不同ENTRY_DATE不同。对于查询

执行计划: -

enter image description here

+0

使用存储过程。不幸的是交易只适用于短期操作。 – buffjape

+1

在事务之外准备一个临时表,删除所有要删除的行的主键值,启动一个事务并发出1条删除语句,将它们全部删除。但是,如果您正在执行的语句都是针对不同的表格,而这不可能。 –

+0

当你说“太多时间”时,你的意思是什么?我们在说毫秒吗?秒?分钟?小时?而“超过30”,在特定场景中有多少? 35? 350? 3500? 350万? –

回答

1

TransactionScope默认Serializable层隔离。这是最安全的级别,但也是最不安全的级别。您经常要明确设置更常见的隔离级别:

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

谢谢你的回答,我会试试这个东西。 – Anup

1

您是否拥有正确的索引设置? 我会建议您为其中一个删除查询提取执行计划,并检查最多的费用。

如果可能的话,添加一个索引来解决问题!

+0

我已经在EmployeeId&Entry_Date上有索引,如果我直接在SQL Server中删除这些查询,那么它也需要时间。这里的问题是锁定和回滚。 – Anup

+0

@Anup是的,我明白查询需要时间,无论你在哪里执行它,但有一些运气,你可以通过查看执行计划,并找出是什么让它如此缓慢运行更快.. – Peter

+0

感谢您的建议,我只是设法运行我的1删除查询并附上执行计划的图像,请指导我,因为我不知道索引太多。 – Anup