同一张表上的多个事务,同时

Posted

技术标签:

【中文标题】同一张表上的多个事务,同时【英文标题】:Multiple transactions on the same table, at the same time 【发布时间】:2012-12-19 17:15:07 【问题描述】:

我遇到了一个问题,我有一个可以由多个线程编辑的表,每个线程创建一个事务来处理这个表,如果一个事务需要很长时间才能完成,其他线程将抛出异常“查询超时已过期”。我猜交易的某个地方有超时设置。

我可以使用线程锁来处理这个问题;但是,有没有办法在服务器端做到这一点?我可以在 SQL Server 中创建锁吗?任何帮助将不胜感激。

【问题讨论】:

你的代码是什么?你试过什么?给人们更多的信息。请阅读faq和How to Ask 【参考方案1】:

您收到的超时不是“事务”超时。这是一般查询超时。此查询可以是 Select、Update、Delete 等。超时值通常在连接字符串中控制。

我不相信您可以专门锁定 SQL Server 中的行、页面或表,这可能是件好事。坦率地说,这不是问题的症结所在。您的交易执行时间过长。它们不应该花费太多时间导致其他查询超时(可能至少 30 秒)。由于交易需要这么长时间,您将让您的服务器陷入瘫痪。一笔交易最多应该保持几秒钟。

我建议您首先查看需要事务的语句(更新、删除或插入),通过 SSMS 中的查询分析器运行它们,并确保没有进行表或索引扫描。我的猜测是这种情况正在发生,并且事务中涉及的表偏大(数十万行或更多)。

【讨论】:

实际上,我使用的表有数十万条记录,因此一个线程可能需要 5 或 10 分钟来更新该表,即完成其事务。我怀疑这是导致其他线程无法在此表上工作并引发异常的原因。 好了。那就是问题所在。您需要找到一种方法将事务时间减少到几秒钟或更短,或者重新构建您的数据库(这可能是必要的)。 感谢您的回答。我想我知道这里发生了什么。我将 IsolationLevel.ReadCommitted 用于事务,这会阻止任何尝试从其他线程访问表并导致其他线程查询超时。使用 IsolationLevel.UnReadCommitted 会有所帮助,但可能会导致脏读。 对。您必须决定读取脏数据的可能性是否可接受。但是,真正的解决方案是重新构建您的交易。 5 到 10 分钟来更新一个只有几十万行的表是很长的时间。我建议您花时间优化当前的工作负载,而不是诉诸 NOLOCK。如果您达到查询超时限制,那么您已经遇到了麻烦,NOLOCK 只会延迟您的清算日。

以上是关于同一张表上的多个事务,同时的主要内容,如果未能解决你的问题,请参考以下文章

同一张表上的多个关系

同一张表上的多个连接,在一个查询中计数

同一张表上的多个连接:转换状态

Mysql在同一张表上的多个左连接

使用 X 和 U 锁在同一张表上发生死锁

深入剖析 HIVE 的锁和事务机制