尝试从 table 中删除行时出错

Error while trying to delete rows from table

我在从 Java 调用的包中有一个 DELETE 语句 delete from test where id = :a。每个会话都试图从相同的 table test 中删除不同的行集,但我仍然收到错误 ORA-00060: deadlock detected while waiting for resource.

任何可能出现问题的帮助。

我可以在跟踪文件中看到以下内容,但我仍然不明白为什么会出现死锁。

*** 2018-08-28 06:55:08.128
DEADLOCK DETECTED ( ORA-00060 )
See Note 60.1 at My Oracle Support for Troubleshooting ORA-60 Errors
[Transaction Deadlock]

The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:

Deadlock graph:
                                          ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name                             process session holds waits  process session holds waits
TM-00049B33-00000000-00000000-00000000        288    2274    SX   SSX      320    2566    SX   SSX
TM-00049B46-00000000-00000000-00000000        320    2566    SX            142    1851    SX   SSX
TM-00049B33-00000000-00000000-00000000        142    1851    SX            288    2274    SX   SSX

session 2274: DID 0001-0120-00000406    session 2566: DID 0001-0140-00000019 
session 2566: DID 0001-0140-00000019    session 1851: DID 0001-008E-0001311B 
session 1851: DID 0001-008E-0001311B    session 2274: DID 0001-0120-00000406

Rows waited on:
  Session 2274: no row
  Session 2566: no row
  Session 1851: no row

是否有任何原因未在跟踪文件中显示 ROWID

目前,当您尝试删除行时,另一个进程似乎正在同时访问这些行。第一个进程锁定这些行。这被称为 "race condition"。 可能是您的包过程导致了问题,也可能是其他原因(您将不得不分析您的代码)。

当任何死锁发生时, 您可以等待几分钟,然后尝试重新执行回滚的语句。

您可以执行 ROLLBACK 并重新执行自上次执行 COMMIT 以来的所有语句。

我不确定这件事..但是你可以参考这个网站link http://www.dba-oracle.com/t_ora_00060_deadlock_detected_while_waiting_for_resource.htm...

死锁由两个相互锁定的会话组成,因此 Oracle 必须取消一个事务以防止它们无限期地保持锁定状态。

假设我删除了第 1 项,你删除了第 2 项,我们都没有提交。

现在我尝试删除项目 2 - 但我不能,因为你未提交的删除正在锁定该行,所以我的会话在阻塞状态等待你提交或回滚你的删除。

现在您尝试删除项目 1。您不能,因为我未提交的删除仍在锁定该行。现在你被我的session屏蔽了,而我已经被你屏蔽了。 (你需要我提交或回滚,但我不能做,因为我被你阻止了。)两个会话将永远等待。

Oracle 检测到这种情况并通过取消和回滚其中一个事务、引发 ORA-00060 并将死锁报告写入数据库警报日志来进行干预。

查看警报日志以了解详细信息,并检查您的应用程序逻辑以防止将来发生这种情况。

编辑 - 感谢您发布跟踪详细信息。

会话 2274 正在等待 2566(以获取 SSX 模式锁)。
会话 2566 正在等待 1851。
会话 1851 正在等待 2274。

关于锁定模式的一些注意事项:https://jonathanlewis.wordpress.com/2010/06/21/locks

SSX(共享子独占)与 'Lock table in share row exclusive mode' 关联。有时锁及其相关模式并不明显,例如insert 到 table 的直接路径或通过外键的级联删除(尤其是在子键未索引的情况下)将导致您可能没有预料到的锁定。

这个问题的答案也可能有一些线索:Finding cause of deadlock error from oracle trace file

这种问题通常是由于缺少索引引起的。如果您的 delete 表达式中的 where 子句没有任意索引,则 oracle 不仅会锁定您要删除的记录,还会执行 table 锁定。 确保您的索引包含删除语句的 where 子句中使用的大部分列。