Oracle 死锁在同一条记录上不断重复
Oracle deadlock keeps repeating on the same record
我对以下查询有疑问:
SELECT o.OID, o.DOSSIER_KEY, o.DOSSIER_TYPE
FROM TVM04_VMAX_TEMP_RIGHTS
WHERE o.DOSSIER_KEY = ?
AND o.DOSSIER_TYPE = ? FOR UPDATE
即使它以不同的时间间隔重复多次,它仍然会导致死锁。如果我了解死锁是如何发生的,我希望两个冲突会话中的一个回滚,另一个继续前进 (here)
我确实得到了 内部异常:java.sql.SQLException:ORA-00060:在等待资源时检测到死锁,但是在我们的系统上另一个 tx 再次访问相同记录的可能性,每次我 运行 手动查询,在我看来接近于 0。
这是我的转储 Oracle 文件:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-00400007-008c00ec 304 786 X 300 757 X
TX-00070016-0002dae6 300 757 X 304 786 X
session 786: DID 0001-0130-011DAD37 session 757: DID 0001-012C-00B1E41F
session 757: DID 0001-012C-00B1E41F session 786: DID 0001-0130-011DAD37
Rows waited on:
Session 786: obj - rowid = 0003921D - AAA5IdAAMAAHjdyAAG
(dictionary objn - 234013, file - 12, block - 1980274, slot - 6)
Session 757: obj - rowid = 0003921D - AAA5IdAARAACfC6AAz
(dictionary objn - 234013, file - 17, block - 651450, slot - 51)
----- Information for the OTHER waiting sessions -----
Session 757:
sid: 757 ser: 387 audsid: 18983600 user: 64/WLSP01
flags: (0x41) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
flags2: (0x40009) -/-/INC
pid: 300 O/S info: user: oracle, term: UNKNOWN, ospid: 42730046
image: oracle@H50A450
client details:
O/S info: user: weblogic, term: unknown, ospid: 1234
machine: H53AD20 program: JDBC Thin Client
application name: JDBC Thin Client, hash value=2546894660
current SQL:
SELECT o.OID, o.DOSSIER_KEY, o.DOSSIER_TYPE FROM TVM04_VMAX_TEMP_RIGHTS o WHERE o.DOSSIER_KEY = :1 AND o.DOSSIER_TY
PE = :2 FOR UPDATE
----- End of information for the OTHER waiting sessions -----
Information for THIS session:
----- Current SQL Statement for this session (sql_id=489bnqugb9wsz) -----
SELECT o.OID, o.DOSSIER_KEY, o.DOSSIER_TYPE FROM TVM04_VMAX_TEMP_RIGHTS o WHERE o.DOSSIER_KEY = :1 AND o.DOSSIER_TYPE
= :2 FOR UPDATE
===================================================
你有什么提示为什么会发生以及如何发生吗?
非常感谢您!
法比奥
我建议使用 SKIP LOCKED 子句来避免其他会话获取已锁定的行进行更新。
它只会锁定它可以select更新的行,其余被跳过的行已经被其他会话锁定。
例如,
会话 1:
SQL> SELECT empno, deptno
2 FROM emp WHERE
3 deptno = 10
4 FOR UPDATE NOWAIT;
EMPNO DEPTNO
---------- ----------
7782 10
7839 10
7934 10
SQL>
第 2 节:
SQL> SELECT empno, deptno
2 FROM emp WHERE
3 deptno in (10, 20)
4 FOR UPDATE NOWAIT;
FROM emp WHERE
*
ERROR at line 2:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
现在让我们跳过会话 1 锁定的行。
SQL> SELECT empno, deptno
2 FROM emp WHERE
3 deptno IN (10, 20)
4 FOR UPDATE SKIP LOCKED;
EMPNO DEPTNO
---------- ----------
7369 20
7566 20
7788 20
7876 20
7902 20
SQL>
因此,department = 10
被 会话 1 锁定,然后 department = 20
被 会话 2 锁定。
另外,看看我的回答here for better understanding of deadlocks. Please read Understanding Oracle Deadlock。