【问题标题】:Oracle deadlock without explicit locking and read committed isolation level, why?没有显式锁定和读取提交隔离级别的 Oracle 死锁,为什么?
【发布时间】:2011-11-10 03:13:21
【问题描述】:

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

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

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

【问题讨论】:

  • Oracle 检测到死锁时,会生成死锁跟踪文件。你能得到那个文件(或者让你的 DBA 把它发给你)吗?有多种可能性,但死锁跟踪文件会准确地告诉您发生了什么。

标签: database oracle spring transactions deadlock


【解决方案1】:

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

仔细检查每个线程正在做什么是起点。可能需要决定不并行运行,或者可能需要使用显式锁定机制(例如 select for update)。

LMK 你发现了什么以及任何其他问题......

K

【讨论】:

  • 好的,我会试着找到那个转储。但从更一般的角度来看:我给线程逻辑卡盘是不相干的。所以这段代码一定要被破解,并提供一些不乱的东西?
  • 如果您的每个线程都接触不同的表,这会使问题更有趣。按照 Justin 和 Steve 的建议,从跟踪文件开始是最好的下一步。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多