oracle – 更新和删除表中的不同行时是否可能出现死锁?

在Oracle 10版本中,即使它们同时在同一个表的不同行上运行,也能在同一个表上更新和删除导致死锁吗?

该表具有由两列组成的主键,并且没有与任何其他表关联/引用的任何FK.并且与其他表没有父/子关系

我相信它不会造成僵局,但我在申请中面临一个问题.

添加oracle跟踪:

以下死锁不是ORACLE错误.由于应用程序设计中的用户错误或发出不正确的临时SQL,这是一个死锁.以下信息可能有助于确定死锁:

Deadlock graph:
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TX-0007003e-0081d6c3        45     790     X            104      20           X
TX-00080043-0085e6be       104      20     X             45     790           X

session 790: DID 0001-002D-000035F9     session 20: DID 0001-0068-000007F6
session 20: DID 0001-0068-000007F6      session 790: DID 0001-002D-000035F9

Rows waited on:
  Session 790: obj - rowid = 0000F0C8 - AAAPDIAAMAAAEfIAAA
  (dictionary objn - 61640, file - 12, block - 18376, slot - 0)
  Session 20: obj - rowid = 0000F0C8 - AAAPDIAAMAAAEfGAAA
  (dictionary objn - 61640, file - 12, block - 18374, slot - 0)

----- Information for the OTHER waiting sessions ----- Session 20:
  sid: 20 ser: 4225 audsid: 57496371 user: 72/RPT_TABLE
    flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
    flags2: (0x40009) -/-/INC
  pid: 104 O/S info: user: oracle, term: UNKNOWN, ospid: 20798
    image: oracle@caidb10p-node1
  client details:
    O/S info: user: gtsgen, term: unknown, ospid: 1234
    machine: caiapp08p-node0.nam.nsroot.net program: JDBC Thin Client
    application name: JDBC Thin Client, hash value=2546894660
  current SQL:
  delete from RPT_TABLE.TEMP_TABLE_T1 where TEMP_T1_ID=:1

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

Information for THIS session:

----- Current SQL Statement for this session (sql_id=bsaxpc2bdps9q) ----- UPDATE RPT_TABLE.TEMP_TABLE_T1 temp1 SET temp1.CLIENT_ID = (SELECT MIN(INVMAP.CLIENT_ID) FROM LI_REF.REF_CLIENT_MAP INVMAP WHERE INVMAP.F_CODE = :B2 AND INVMAP.AID = temp1.ID AND temp1.R_ID=:B1 )
----- PL/SQL Stack -----
----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
45887d750        24  procedure RPT_TABLE.T1_UPDATE_StoredProc  

6399ba188         1  anonymous block
最佳答案
如果您可以使用死锁图更新您的问题,那将是有用的信息. (当您的应用程序遇到死锁时,Oracle将引发ORA-00060,并将跟踪文件写入user_dump_dest.)如果您查看跟踪文件,您将找到一个名为“死锁图”的部分.如果你可以发布它,并发布导致死锁的语句和死锁中涉及的其他语句,那么我们可以开始得出一些结论. (我请求的所有信息都可以在跟踪文件中找到.)

正如Alessandro所提到的,由于父/子关系的子表上没有索引的外键,会话可能会锁定同一个表中的不同行.此外,如果表中缺少ITL条目,即使表不是父/子关系的一部分,也可能会在两个会话中更新同一表的不同行的死锁.

再次,发布上面要求的信息,我相信我们可以确定你的僵局的根本原因.

 在2012年7月30日添加**

添加以下内容,现在已经提供了死锁跟踪文件:
好的,首先,基于跟踪文件内容,这是一个简单的死锁,因为会话在他们试图锁定的行上重叠/冲突.尽管你之前对不同行的死锁有任何评论,但我在这里告诉你,这个特定的死锁是由于同一行上的行级锁定造成的.

死锁图显示锁保持模式的事实是’X'(不包括),锁等待的模式是’X’,这告诉我这是简单的行级锁定.

在这种情况下,SID 20正在执行“从RPT_TABLE.TEMP_TABLE_T1删除,其中TEMP_T1_ID =:1”并且已经对rowid AAAPDIAAMAAAEfIAAA进行了锁定.

同时,SID 790正在执行“RPT_TABLE.T1_UPDATE_StoredProc”,同时已经对rowid AAAPDIAAMAAAEfGAAA进行了锁定.

从跟踪文件的“Rows waited on”部分注意到,SID 20正在等待SID 790持有的行并且SID 790正在等待SID 20持有的行.这是一个典型的僵局.

一些其他信息:

> Enqueue类型是TX(参见死锁图),因此,由于未编入索引的外键,这肯定不会锁定.如果由于未编制索引的FK而锁定,则入队类型将是TM,而不是TX. (至少还有一个涉及TM队列的情况,并且它不是未编入索引的FK.所以,不要认为TM队列总是意味着未编入索引的FK.)
>锁等待的模式是’X'(不包括),因此这是行级锁定.如果等待的模式是’S'(共享),则它不会是行级锁定.相反,它可能是ITL短缺或PK或英国执法.

希望有所帮助!

转载注明原文:oracle – 更新和删除表中的不同行时是否可能出现死锁? - 代码日志