当多个用户正在使用该应用程序时,我的应用程序中经常出现这种“等待资源时检测到ora-00060死锁”的错误。我从oracle Admin获得了跟踪文件,但需要帮助才能阅读它。下面是跟踪文件中的一些数据,我希望这有助于找到原因。
*** 2013-06-25 09:37:35.324
DEADLOCK DETECTED ( ORA-00060 )
[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-000151a2-00000000 210 72 SX SSX 208 24 SX SSX
TM-000151a2-00000000 208 24 SX SSX 210 72 SX SSX
session 72: DID 0001-00D2-000000C6 session 24: DID 0001-00D0-00000043
session 24: DID 0001-00D0-00000043 session 72: DID 0001-00D2-000000C6
Rows waited on:
Session 72: no row
Session 24: no row
----- Information for the OTHER waiting sessions -----
Session 24:
sid: 24 ser: 45245 audsid: 31660323 user: 90/USER
flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
flags2: (0x40009) -/-/INC
pid: 208 O/S info: user: zgrid, term: UNKNOWN, ospid: 2439
image: oracle@xyz.local
client details:
O/S info: user: , term: , ospid: 1234
machine: xyz.local program:
current SQL:
delete from EMPLOYEE where EMP_ID=:1
----- End of information for the OTHER waiting sessions -----
Information for THIS session:
----- Current SQL Statement for this session (sql_id=dyfg1wd8xa9qt) -----
delete from EMPLOYEE where EMP_ID=:1
===================================================
如果有人可以告诉我“死锁图::”的含义,我将不胜感激。在节上等待的行也表示没有行。
我还在一些博客中读到跟踪文件中的“sqltxt”部分可以提示原因。以下是我在该部分中看到的查询。
select /*+ all_rows */ count(1) from "USERS"."EMPLOYEE_SALARY" where EMPSAL_EMP_ID=:1
employee_salary表在EMPSAL_EMP_ID列上具有外键约束。
sql提示说“all_rows”,这是否意味着当从employee表中删除记录时,此表会获得表级锁定?我目前没有外键列的索引。在此列上添加索引会有帮助吗?
请发布,以防需要更多信息。
由于
答案 0 :(得分:29)
首先,select
语句永远不会锁定Oracle中的任何内容,只使用最后一个可用的一致数据版本。自{6}以来select ... for update
之后的update
数据锁不是自Oracle 9i以来的情况,但查询中没有for update
子句。
Resource Name process session holds waits process session holds waits
TM-000151a2-00000000 210 72 SX SSX 208 24 SX SSX
会话#72保持具有“行独占”类型(SX)的表级锁(TM)并且想要在同一表上获取“共享行独占”(SSX)锁。会话#24已阻止此会话,该会话已保持相同类型(SX)的表级锁定,并在SSX锁定可用时等待。
Resource Name process session holds waits process session holds waits
TM-000151a2-00000000 208 24 SX SSX 210 72 SX SSX
这(第二行)演示了完全相同的情况,但反方向:会话#24等待SSX锁定变为可用,但被会话#72阻止,该会话已经在同一个表上保存了SX锁。
因此,Sessions#24和Session#72相互阻塞:发生死锁。
两种锁类型(SX和SSX)都是表级锁 要了解这种情况,我建议您阅读Franck Pachot的this article。
以下是本文的引文,与您的情况直接相关(请注意,SSX和SRX缩写是等效的):
参照完整性也获得TM锁。例如,常见的 使用未编入索引的外键导致子表上的S锁定时 您在父表上发出删除或更新密钥。这是 因为没有索引,Oracle没有单一的低级资源 锁定以防止可能违反的并发插入 参照完整性。
当外键列是领先的 常规索引中的列,然后是父项的第一个索引项 value可以用作单个资源,并使用行级TX锁定 锁定。
如果参照完整性有删除级联怎么办?在 除S模式外,还有意更新中的行 子表,与行X(RX)模式一样。这是共享行的位置 独占(SRX)发生:S + RX = SRX。
因此,最可能的变体是会话#72和会话#24同时删除EMPLOYEE
表中的某些行,并且on delete cascade
的{{1}}约束与缺席相关联EMPSAL_EMP_ID
列中的索引,其中EMPLOYEE_SALARY
列首先列出。