【发布时间】:2013-06-07 14:16:52
【问题描述】:
我有一个存储更新语句的类。我无法在我的并行 for 循环中执行这些语句,因为这会导致死锁。
语句在循环完成后执行,在 100 行的情况下它可以正常工作。但某些场景会生成超过 100,000 条语句。在顺序循环上执行这些语句需要很长时间。
我希望实现的是,在类中添加 100 条语句后,我在单独的线程上执行这些语句,并清除 statements 变量,以便可以添加并执行接下来的 100 条。
我是多线程的新手。这是可以实现的吗?如果不是我使用什么其他选项来减少执行时间。请注意,我无法更改语句逻辑,因为它附加了许多其他因素。
让我进一步澄清我的情况。我拥有的那个表更像是一个日志表,它跟踪传输到客户端的 sql 行,因此我不会重新发送相同的对象两次。这是为了减少通过 Internet 链接传输对象时的带宽使用量。
一开始,我一收到客户的回复就执行每条语句。当循环是连续的时,这很有效,但被证明太慢了。所以我选择使用并行 for 循环。这就是所有问题都出现的地方,因为几乎同时从同一个表中选择、插入和更新导致死锁。
所以我决定将语句保存在字符串列表中,以便稍后执行。
我尝试使用 string.join 将所有字符串转换为单个字符串,但这给了我系统内存不足异常。从而一个一个地依次执行它们。现在转移需要 5 分钟,执行需要 30 分钟。所以我正在寻找解决方案..
【问题讨论】:
-
你能出示你的陈述吗?可能您的 SQL 代码需要在编写时考虑到线程。
-
或许你应该看看 SQLBulkCopy msdn.microsoft.com/en-us/library/…
-
您可以结合使用连接池和并行 for 循环来解决此问题。
-
与其从您的应用程序中逐一调用语句,不如让您的应用程序构建一个包含所有更新的 SQL 语句并让 SQL 来解决这个问题?
-
使用单个线程来实际执行工作是正确的想法。它可以监视待处理更新队列并定期执行更新,例如当挂起的更新计数在最后一次更新后达到 100 或 5 秒时,以先到者为准。正如 Valverij 建议的那样,将它们分组到一个更新中将提高性能。