更新提交以避免死锁

Posted

技术标签:

【中文标题】更新提交以避免死锁【英文标题】:Updating on commit to avoid deadlocks 【发布时间】:2013-08-14 16:54:31 【问题描述】:

我有一个表跟踪另一个表分区的最后更新时间,因此我们的协调器只需要检查自上次协调以来已更新的分区。有多个线程更新分区表,因此每次更新最新更新时间表的同一行多次。这显然会导致死锁。有没有办法通过只在提交时更新一次来防止这些死锁?

我在考虑可能使用会话本地临时表,但不确定如何在提交时将值传输到全局表。

【问题讨论】:

【参考方案1】:

没有办法在提交时触发进程,因此这种方法可能行不通。

潜在地,您可以让每个写入器进程写入 Oracle 高级队列 (AQ),然后让另一个进程将消息出队并将它们实际应用到当前表。这意味着在编写器会话提交和 AQ 处理器拾取和处理消息之间会有一些延迟,但这种延迟不应该太长。如果您不想使用 AQ,您可以通过让每个写入器线程插入到类似队列的表中并让单独的线程处理该表来做同样的事情。

不过,我对您所描述的过程如何导致死锁感到困惑。您真的在谈论死锁(即抛出 ORA-00060 错误并生成死锁跟踪文件)吗?您所描述的应该导致阻塞锁,而不是死锁,除非发生的事情比您告诉我们的要多。

【讨论】:

这些线程中的每一个都批量写入,以便每次提交可以更新 200 个不同的行。由于每个线程可能会以不同的顺序更新每一行,因此会导致死锁。 @drakkanraz - 为什么不更改编写器,以便它们在批处理结束时以特定顺序更新跟踪表中的行? 我认为这是一个很好的建议。我试图在存储过程中执行此操作以确保不会忘记它,但可以在所有其他插入完成后在代码中完成。感谢您的帮助

以上是关于更新提交以避免死锁的主要内容,如果未能解决你的问题,请参考以下文章

怎么避免mysql死锁

数据库死锁处理方法

避免与 Future 阻塞 发生死锁

多线程死锁避免

mysql 开发进阶篇系列 14 锁问题(避免死锁,死锁查看分析)

死锁产生的原因及避免死锁的方法