部署在多台机器上的应用程序 - 访问同一个数据库表。它读取 MIN 行,然后删除该行。
当这种情况同时发生时,我们会从 DB2 中得到一个 -913 错误,表示死锁。
已经尝试过以下选项 1. 锁定行。2. 应用程序代码中的重试机制,死锁发生后。
似乎没有任何效果。
任何想法/参考/解决方案?
泰
检查与您的 SQL0913N 关联的原因代码以确定问题实际上是死锁(原因代码 2)还是只是锁定超时 (>2)。
如果问题确实是死锁,您可以通过为死锁激活 DB2 事件监视器来捕获有关死锁的详细跟踪信息。如果您尚未捕获 Hibernate 代表您生成的特定语句,您可能还需要定义和激活 SQL 语句事件监视器以捕获尽可能多的细节。
Hibernate 使用的隔离级别会对并发性产生很大影响。通常,当应用程序可以通过未提交的读取隔离执行脏读时,它们会遇到较少的锁定,但这种方法并不理想,因为它会暴露未提交的数据并破坏 DB2 的 ACID 属性。如果您已经启用了脏读,则它可能会导致您的特定问题,因为具有未提交更改的行在其他连接中可见,而不是被锁定。
您的应用程序的设计(多线程访问实际上是单个工作队列)可能并不理想,并且可能会从重构中受益。哲学家进餐问题提供了多种解决方案来减少争用。根据您的应用程序的具体情况,您可能能够更改处理行的方式,例如尽早设置状态标志,这将帮助其他线程了解该特定行已被另一个线程处理并且可以跳过. 对事务边界的细微调整也可能会导致更频繁的提交,从而缓解问题。
DB2 9.7(2009 年 6 月发布)中更值得注意的改进之一是对游标稳定性隔离的增强,它提供了对锁定行的当前提交版本的访问。