Oracle死锁一直在重复记录

时间:2015-04-16 12:48:23

标签: oracle jpa deadlock

我遇到以下问题的问题:

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
===================================================

你有没有暗示为什么以及如何发生?

非常感谢你!

的Fabio

1 个答案:

答案 0 :(得分:0)

我建议使用 SKIP LOCKED 子句来避免其他会话获取已经锁定的更新行。

它只会锁定它可以选择更新的行,其余被跳过的行已被其他会话锁定。

例如,

第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,以便更好地了解死锁。请阅读Understanding Oracle Deadlock