0

我在带有 SQL Server 2012 的 .NET 4.5 上使用 Entity Framework 5。我有一个函数可以从第三方源下载大量数据并将其解析到我的数据库中。它以 2,500 条记录为单位下载、解析到我的实体并插入/更新到我的数据库。

对于我的数据库的插入/更新,我正在使用 SqlBulkCopy 类。当它对我的数据库进行插入/更新时,它正在插入/更新到的表似乎部分没有响应。如果我从 SSMS 运行一个简单的选择查询,它将提取一些记录,然后挂起,直到应用程序完成批量插入/更新。我的数据库中的这些数据通过 WCF 服务馈送到多个源,如果我尝试在其中一个源加载数据,由于数据库没有响应数据,它会超时。插入/更新完成后,WCF 服务和 SSMS 查询都将继续正常运行。

我认为这可能是由于 SqlBulkCopy 造成的,所以我删除了该类的使用,只调用了一个 context.SaveChanges() ,它产生了完全相同的结果。然后,我进行了一项测试,将 EF 完全排除在外,并使用经典的 ADO.NET(没有 SqlBulkCopy),一切正常。我重新插入了 SqlBulkCopy,将 EF 排除在外,然后表似乎被锁定,直到它完成。

所以我假设这里的罪魁祸首是 EF 和 SqlBulkCopy。关于如何解决这个问题并仍然使用 EF 和 SqlBulkCopy 的任何想法?或者是什么可能导致这种情况发生?

我认为这里不需要我的代码示例,但是如果您想查看,请告诉我。提前致谢。

4

1 回答 1

1

我想这是因为交易。当您使用 SqlBukCopy 或 context.SaveChanges() 时,插入发生在事务中。当您用经典的 ADO.NET 替换该代码时,您是将插入包装在事务中还是让每个插入发生在它自己的隐式事务中?

当事务处于挂起状态时,它会锁定正在更新的表的部分。如果它插入足够多的数据,它可能会锁定表或整个表中的很多页(这称为锁升级)。

解决此问题的最佳方法是将更新拆分为更小的块。还有一些其他选项(例如读取未提交的数据等),但这些选项有很大的缺点,通常应该避免。

于 2012-11-12T23:00:45.020 回答