SqlBulkCopy在事务内部插入时阻止对表的任何其他写入

asp.net c# sql sqlbulkcopy sql-server

在我的Web应用程序中,用户可以一次插入大量数据,以提高我使用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中应用的锁,似乎是由于bulkcopy类导致在表对象上设置了独占锁(X),就好像您要一次插入一个只应用了意图锁在桌子上(九)。仍然不确定是否有办法解决这个问题,但我认为这是由于锁定升级造成的。

更改表索引上的允许页锁定以及更改批量副本的批量大小已经在我的一些测试中完全锁定,但它们是不稳定的。

热门答案

IsolationLevel仅引用读取而不是写入。如果您的某个客户端正在写入数据,则另一个客户端应该能够在事务开始之前读取数据,但是,它将无法同时写入。



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因