通过同一个Oracle DB表在多个服务器上运行Spring Batch应用程序,不时会产生死锁错误。应用程序隔离级别为 READ COMMITTED ,作业以 throtle-limit 10 执行。
应用程序正在查询数据库表,处理数据库中的项目并更新相同的项目。一列给出了JobId值,使得应用程序的两次执行不可能处理同一组行。
例如,如果一个服务器使用JobId A和另一个服务器B查询行,则它们之间应该没有问题:
RowId JobId Status value
--- ----- ------ -----
1 A 0 aaa
2 A 0 bbb
3 B 0 ccc
4 B 0 ddd
我发现了这个类似的post,其中指出同一个Job的不同线程可能正在争夺同一行。在我的情况下,我有两次执行应用程序在同一秒内崩溃与死锁。这让我觉得不是关于相同执行的线程,而是它们之间的不同执行。
我从数据库管理员处获得了死锁跟踪:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-002b001e-000062c6 177 829 X 51 919 S
TX-004f0004-00001313 51 919 X 177 829 S
session 829: DID 0001-00B1-00000058 session 919: DID 0001-0033-0000080F
session 919: DID 0001-0033-0000080F session 829: DID 0001-00B1-00000058
Rows waited on:
Session 829: obj - rowid = 000117C5 - AAARfFAALAAI5iEAAA
(dictionary objn - 71621, file - 11, block - 2332804, slot - 0)
Session 919: obj - rowid = 000117D1 - AAARfRAALAAIO+YAAA
(dictionary objn - 71633, file - 11, block - 2158488, slot - 0)
我还发现其他post解释了如何到达受影响的行,但我不是系统管理员。有没有办法从死锁跟踪文件中提取更多信息?可能这是一个新手问题,但是对于死锁中的两个会话,rowid的第一部分是否应该相同?我在互联网上看到的所有样本都是一样的。这里是000117C5和000117D1,它们看起来在两个不同的块(2332804和2158488)内。这些值是否也可能是其他值的时间值?