没有显式锁定和读取提交隔离级别的Oracle死锁,为什么?

时间:2011-09-04 15:05:16

标签: database oracle spring transactions deadlock

我收到此错误Message: ORA-00060: deadlock detected while waiting for resource,即使我没有使用任何显式表锁定,并且我的隔离级别设置为READ COMMITTED

我使用Spring TransactionTemplate上的多个线程进行默认传播。在我的业务逻辑中,数据是分开的,因此两个事务永远不会有相同的数据集。因此,我不需要SERIALIZABLE

为什么Oracle会检测到死锁?在这个星座中死锁是不可能的,或者我错过了什么?如果我没有遗漏任何东西,那么我的分离算法一定是错的,对吧?或者还有其他一些解释吗?

2 个答案:

答案 0 :(得分:4)

Oracle默认执行行级锁定。你提到使用多个线程。我怀疑一个线程正在锁定一行,然后尝试锁定另一个已被另一个线程锁定的线程。那个其他线程然后试图锁定第一个线程锁定的行。此时,Oracle将自动检测死锁并将其中断。上面提到的两行可以在同一个表中,也可以在不同的表中。

仔细审查每个线程正在做什么是起点。可能有必要决定不并行运行,或者可能需要使用显式锁定机制(例如选择更新)。

你发现的LMK以及任何其他问题....

K

答案 1 :(得分:1)

遇到死锁本身与序列化级别无关。当插入/更新/删除行时,oracle会锁定该行。如果有两个并发运行的事务并尝试更改同一行,则可能会遇到死锁。强调“CAN”。如果不同类型的事务以不同的顺序锁定,这通常会发生这种情况,这是交易设计不良的标志。

如前所述,在遇到死锁时会生成跟踪文件。如果查看跟踪文件,可以确定死锁中涉及哪两个会话。此外,它还显示了相应的SQL语句。