Oracle死锁错误

时间:2014-05-02 19:37:46

标签: oracle hibernate deadlock database-deadlocks

*** 2014-04-29 05:48:49.364
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
TX-0006001e-0092c9ce       352    1558     X            413     504           X
TX-000c000c-00529f7e       413     504     X            352    1558           X

session 1558: DID 0001-0160-00064122    session 504: DID 0001-019D-0005CF62 
session 504: DID 0001-019D-0005CF62 session 1558: DID 0001-0160-00064122 

Rows waited on:
  Session 1558: obj - rowid = 00364D23 - AANk0jADXAAABe7AAm
  (dictionary objn - 3558691, file - 215, block - 6075, slot - 38)
  Session 504: obj - rowid = 00364D25 - AANk0lADXAAABkeAEK
  (dictionary objn - 3558693, file - 215, block - 6430, slot - 266)

----- Information for the OTHER waiting sessions -----
Session 504:
  sid: 504 ser: 7765 audsid: 122682168 user: 1699/SWEEPER_RW_USER_0CD40
    flags: (0x41) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
    flags2: (0x40009) -/-/INC
  pid: 413 O/S info: user: oracle, term: UNKNOWN, ospid: 31932
    image: oracle@db-prod.xyz.xyz.com
  client details:
    O/S info: user: myuser, term: unknown, ospid: 1234
    machine: xyz program: JDBC Thin Client
    application name: sweeper_rw, hash value=1328634095
  current SQL:
  update ACT.PERSON_EVENT set PERSONID=:1  where SEQUENCE=:2 

----- End of information for the OTHER waiting sessions -----

Information for THIS session:

----- Current SQL Statement for this session (sql_id=a4nxmk0w7gd6v) -----
select * from ( /* criteria query */ select this_.SEQUENCE as SEQUENCE0_0_, this_1_.CHANGE_TYPE as CHANGE2_0_0_, this_1_.CREATED_UTC as CREATED3_0_0_, this_1_.EFFDT_UTC as EFFDT4_0_0_, this_1_.UPDATED_UTC as UPDATED5_0_0_, this_1_.STATUS as STATUS0_0_, this_.PERSONID as PERSONID1_0_ from ACT.PERSON_EVENT this_ inner join ACT.EVENT this_1_ on this_.SEQUENCE=this_1_.SEQUENCE where this_1_.STATUS=:1  and this_1_.EFFDT_UTC<=:2  and this_1_.CREATED_UTC<=:3  ) where rownum <= :4  for update

我有两个表ACT.EVENT(父)和ACT.PERSON_EVENT(子)使用hibernate表建模,每个子类继承一对一关系。

ACT.EVENT
-SEQUENCE (PK)
-STATUS
-CHANGE_TYPE
-CREATED_UTC
-UPDATED_UTC

ACT.PERSON_EVENT
-SEQUENCE (PK, FK)
-PERSONID

我有很多线程可以选择STATUS =&#39; NEW&#39;使用上述选择的事件...其中rownum&lt; = 50表示更新子句,然后更新状态=&#39; PENDING&#39;然后提交。然后他们做了一些工作并更新了STATUS =&#39; COMPLETE&#39;。这是因为不同的线程不会处理相同的事件。有人能告诉我为什么会发生这种情况,因为不同的线程不应该拿起相同的项目来处理。

以下是在不同会话中执行的步骤。

SESSION-A(选择&#39;新&#39;活动并更新为&#39;待定&#39;)

select
    * 
from
    ( /* criteria query */ select
        this_.SEQUENCE as SEQUENCE0_0_,
        this_1_.CHANGE_TYPE as CHANGE2_0_0_,
        this_1_.CREATED_UTC as CREATED3_0_0_,
        this_1_.EFFDT_UTC as EFFDT4_0_0_,
        this_1_.UPDATED_UTC as UPDATED5_0_0_,
        this_1_.STATUS as STATUS0_0_,
        this_.PERSONID as PERSONID1_0_ 
    from
        ACT.PERSON_EVENT this_ 
    inner join
        ACT.EVENT this_1_ 
            on this_.SEQUENCE=this_1_.SEQUENCE 
    where
        this_1_.STATUS='NEW' 
        and this_1_.EFFDT_UTC<=? 
        and this_1_.CREATED_UTC<=? ) 
where
    rownum <= 50 for update




  update
            ACT.EVENT 
        set
            CHANGE_TYPE=?,
            CREATED_UTC=?,
            EFFDT_UTC=?,
            UPDATED_UTC=?,
            STATUS='PENDING'
        where
            SEQUENCE=?

    COMMIT;

SESSION-B(做一些工作,将活动附加到新会话并完成&#39;)

  update
            ACT.PERSON_EVENT 
        set
            PERSONID=? 
        where
            SEQUENCE=?

update
        ACT.EVENT 
    set
        CHANGE_TYPE=?,
        CREATED_UTC=?,
        EFFDT_UTC=?,
        UPDATED_UTC=?,
        STATUS=? 
    where
        SEQUENCE=?

COMMIT;

感谢, 灰

1 个答案:

答案 0 :(得分:0)

您的FOR UPDATE select会锁定连接中包含的两个表,而只更新ACT.EVENT表 - 您应该只锁定计划更新的表中的行。

因此,会话A的选择应该像(或EVENT表中的任何一列)结束:

 rownum <= 50 for update of ACT.EVENT.CHANGE_TYPE

正如其他人在这里问到的: enter link description here