15

当多个用户使用该应用程序时,我现在经常在我的应用程序中收到此“在等待资源时检测到 ora-00060 死锁”错误。我从 oracle 管理员那里得到了跟踪文件,但在阅读它时需要帮助。以下是跟踪文件中的一些数据,我希望这有助于找到原因。

*** 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”,这是否意味着从员工表中删除记录时该表获得表级锁定?我目前在外键列上没有索引。在此列上添加索引会有所帮助吗?

请张贴,以防需要更多信息。

谢谢

4

1 回答 1

35

首先,select语句从不锁定 Oracle 中的任何内容,只使用最后可用的一致数据版本。自 Oracle 9i 以来,它不是select ... for update锁定数据的情况update,但问题的查询中没有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 阻塞,会话 #72 已经在同一张表上持有 SX 锁。

因此,会话#24 和会话#72 相互阻塞:发生死锁。

两种锁类型(SX 和 SSX)都是表级锁。
要了解这种情况,我建议阅读Franck Pachot 的这篇文章

以下是本文的引文,与您的情况直接相关(请注意,SSX 和 SRX 缩写是等效的):

参照完整性也获得 TM 锁。例如,当您在父表上对键发出删除或更新时,未索引外键的常见问题会导致子表上的 S 锁。这是因为没有索引,Oracle 没有单个较低级别的资源可以锁定,以防止可能违反参照完整性的并发插入。
当外键列是常规索引中的前导列时,具有父值的第一个索引条目可以用作单个资源并使用行级 TX 锁进行锁定。
如果参照完整性有一个删除级联怎么办?除了 S 模式之外,还有更新子表中的行的意图,就像 Row X (RX) 模式一样。这是共享行独占 (SRX) 发生的地方:S+RX=SRX。

因此,最可能的变体是 Session #72 和 Session #24EMPLOYEE同时删除了表中的一些行,并且对于首先列出的列中的表上没有索引存在on delete cascade约束。EMPSAL_EMP_IDEMPLOYEE_SALARYEMPSAL_EMP_ID

于 2013-06-28T11:59:16.187 回答