我有一个用C#开发的Windows服务。此服务将XML文件中的数据导入SQL Server数据库,导入到不同的表中。这些XML文件很大。 500 MB大小的特定文件需要超过1小时才能导入到包含数百万行的表中。
我有一个在ASP.NET MVC中开发的Web应用程序,上面的数据库位于此应用程序的后端。此应用程序通过过滤此数据库的表中的相关记录来显示不同的报告。此应用程序也会操纵记录。
当我在Windows服务导入XML文件期间运行应用程序与数据库交互时,我的Web应用程序挂起,并在很长一段时间后发生超时错误。
我在Windows服务的存储过程中使用简单的插入更新命令,并且这些存储过程中没有事务。
请告知任何解决方案以避免此问题。
答案 0 :(得分:1)
您可以像这样增加命令时间
cmd.CommandTimeout = 3600; // in seconds
您还必须查看存储过程为何超时 你的查询打破了某些地方
答案 1 :(得分:1)
根据我的经验,我可以提出一些建议。
首先在单个交易中推送500MB的整个数据是不可取的。
然后制作必要的保存点,如果所有事务都成功,最后提交保存点。
因为不建议长时间保持连接对象。如果您仍然需要,可以尝试增加sql server超时。但这是一个糟糕的方法。
最好是拆分xml内容并尝试使用保存点并最终提交所有事务。
不要以为你只是做一个简单的插入或更新命令。如果您的列上有索引,则这些记录需要很长时间。
确保您拥有正确的索引并且只有必要的索引。
如果您有任何疑问,请在此处回复。您在当前代码中使用的方法是什么?
答案 2 :(得分:0)
任何 SQL Server INSERT
或UPDATE
命令在事务中运行 - 无论您是否指定一个。如果您自己未指定任何内容,SQL Server将使用隐式事务来确保语句的数据完整性。
默认情况下,SQL Server使用行级锁,例如它只锁定正在插入或更新的行。但是,如果该事务将影响超过5000行,则SQL Server将执行锁定升级并使用全表独占锁替换5000个单独的行级锁,直到操作已完成,事务已提交(或回滚)。
在此期间,没有其他操作 - 甚至不是SELECT
,都可能针对该表....
唯一的解决方案是在没有其他操作针对数据库运行的情况下运行这些导入,或者将这些插入拆分为可以单独提交的少于5000行的较小块。
答案 3 :(得分:0)
您可以增加配置文件中的最大连接数。这是我的配置文件:
<connectionStrings>
<add name="local" connectionString="user id=sa;password=test+;Data Source= (local);Max Pool Size=500;Pooling=true;Database=user" providerName="System.Data.SqlClient" />
</connectionStrings>
我已设置最大泳池尺寸= 500
答案 4 :(得分:0)
如果您正在运行SQL Server Enterprise Edition,那么您应该利用Table Partitioning。您可以做什么,特别是数据加载,将数据加载到临时表,然后将分区切换到最终表。这将消除加载过程中最终表上的任何表级锁定,因此您的报告可以在加载发生的同时运行。这里的副产品是加载的数据在加载过程完成并切换分区之前将无法查看报告。
你会想要正确地设计它,因为它取决于我不会在这篇文章中引入细微差别的各种因素,但是有很多关于这个的博客你可以找到:here's one以供参考,让您前进。
答案 5 :(得分:-1)
您应该尝试使用(nolock)选项。 This SO提供了有关Nolock的详细信息。如果您正在使用像EntityFramework这样的ORM,那么我们需要仔细查看代码。