数据库
首页 > 数据库> > c#-在事务内部插入SqlBulkCopy会阻止对表进行任何其他写操作

c#-在事务内部插入SqlBulkCopy会阻止对表进行任何其他写操作

作者:互联网

在我的Web应用程序中,用户可以一次插入大量数据,以提高性能,我正在使用SqlBulkCopy类.对于单个操作插入到两个不同的表中,它将运行多次.如果用户取消操作或操作失败,那么我需要回滚数据,以便使用隔离级别快照将所有内容包装在事务中.

据我了解,使用快照隔离将允许其他用户同时对表进行写/读.但是,在进行一次数据上传时,它将阻止对表的任何其他写入,直到整个父事务完成为止.

这是一些显示该问题的简化代码.我排除了许多功能,但想法仍然相同.我遍历了一些in内存集合,将它们批量复制到表中,取出它们,然后批量复制到另一个表中.

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),就像您一次插入一个锁一样,仅应用了意图锁在桌子上(IX).仍然不确定是否可以解决此问题,但是我认为这是由于锁升级所致.

在我的一些测试中,更改表索引上的“允许”页面锁和更改批量副本的批处理大小已经完全锁定了,但它们是有气质的.

解决方法:

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

标签:sqlbulkcopy,asp-net,sql,c,sql-server
来源: https://codeday.me/bug/20191119/2035237.html