Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用实体框架w/SqlBulkCopy运行插入/更新时数据库表无响应_C#_Asp.net_Sql Server_Wcf_Entity Framework - Fatal编程技术网

C# 使用实体框架w/SqlBulkCopy运行插入/更新时数据库表无响应

C# 使用实体框架w/SqlBulkCopy运行插入/更新时数据库表无响应,c#,asp.net,sql-server,wcf,entity-framework,C#,Asp.net,Sql Server,Wcf,Entity Framework,我在SQL Server 2012中使用.NET 4.5上的Entity Framework 5。我有一个功能,可以从第三方源下载大量数据,并将其解析到我的数据库中。它下载、解析我的实体,并批量插入/更新我的数据库,共2500条记录 对于数据库的插入/更新,我使用SqlBulkCopy类。当它对我的数据库进行插入/更新时,它插入/更新的表似乎部分没有响应。如果我从SSMS运行一个简单的select查询,它将提取一些记录,然后挂起,直到应用程序完成批量插入/更新。我的数据库中的数据通过WCF服务提

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

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

我认为这可能是由于SqlBulkCopy,所以我取消了该类的使用,只调用了一个context.SaveChanges(),它会产生完全相同的结果。然后我运行了一个测试,将EF完全排除在外,并使用了经典的ADO.NET(没有SqlBulkCopy),一切都很好。我重新插入SqlBulkCopy,将EF忽略,然后再次将表锁定,直到完成

所以我假设罪魁祸首是EF和SqlBulkCopy。有什么想法可以让我绕过这个问题,仍然使用EF和SqlBulkCopy吗?或者是什么导致了这种情况的发生


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

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

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


最好的解决方法是将更新分割成更小的块。还有一些其他选项(如读取未提交的数据等),但这些选项有明显的缺点,通常应避免使用。

我认为这是一种服务器设置。我的一个客户端使用的共享托管服务器上出现了这个问题。在传输数据时,我甚至无法选择TOP 1。它只会在那里“执行查询…”30-45分钟。这不是一个共享服务器。数据库运行在一个sql集群中,该集群由2个具有中央存储的节点组成。一次只能运行一个,另一个是故障切换。该应用程序托管在另外两台负载平衡的专用web服务器上。长时间的“执行查询”与我在SSMS中的体验是一样的。如果您知道这可能是什么设置,它可能会有所帮助。我已经阅读了有关SqlBulkInsert默认情况下执行的行锁的内容。我也能理解它是在交易中完成的。但是,如果是这种情况,select查询是否仍会执行,但会排除与事务相关的记录?至于ADO.NET,我没有将它们封装在事务中,而是在它们自己的隐式事务中执行。我将尝试将它分成小块(可能是500?),还将尝试将ADO.NET版本包装到事务中,并查看结果。感谢您的输入。选择查询不能排除交易中涉及的记录;这将违反关系数据库所坚持的数据完整性的一些基本原则。换句话说,如果select需要读取锁定的数据,则必须等待。另外,即使默认情况下SqlBulkInsert执行行锁定,当插入足够的数据时,锁也可以升级为页锁或表锁。我尝试仅使用ADO.NET和事务插入50000条记录。在comm.ExecuteNonQuery()期间(这是花费所有时间的),表继续正常响应。我在ExecuteNonQuery()函数的正下方的transaction.Commit()行上放置了一个断点,当断点到达提交行时,表将停止响应,就像使用EF&SqlBulkCopy一样。当我走到没有时间延迟的地方时,桌子开始恢复正常。因此,看起来这肯定是事务的提交。我认为这里最好的解决方案是甚至不使用EF或SqlBulkCopy进行插入,只使用ADO.NET,每个记录都独立插入,没有事务。事务并不重要,因为如果它在中途出错,剩余的记录将在下一次下载时提取。除非您知道一种不使用EF/SqlBulkCopy事务的方法,我查找了它,但没有找到;它是专门为这个目的制作的。它可以很好地控制事务、批量大小。最重要的是,它的运行速度远远超过50000次插入。