2

刚得到ORA-00060: deadlock detected while waiting for resource

我有一个锁定行中特定列的查询,我想知道 oracle 如何在查询匹配的行上设置锁定?它是原子的还是非原子的?

例如,我有带有idvalue列的表和以下查询:

select id, value from tbl where id > 1 and id < 100 for update of value

有几个客户端执行此查询。在这种情况下是否有可能陷入僵局?

4

1 回答 1

4

在这种情况下是否有可能陷入僵局

当两个或多个会话试图获取彼此锁定的资源的排他锁时,这是可能的。

这是一个简单的演示:

  create table Deadlock1(col number);

  create table DeadLock2(col number);

  insert into DeadLock1(col) values(1);
  insert into DeadLock2(col) values(1);

会议#1

  select *
    from deadlock1
   where col = 1
     for update of col

会议#2

  select *
    from deadlock2
   where col = 1
     for update of col

会议#1

  select *
    from deadlock2
   where col = 1
     for update of col

会议#2

  select *
    from deadlock1
   where col = 1
     for update of col

如果在会话 #1 中未发出提交或回滚,则尝试在会话 #2 中获取锁定,将导致ORA-00060: deadlock detected while waiting for resource.

在您的情况下,当 session#1 正在执行您的查询并且没有commitorrollback时, session #2 将被阻止。不会出现僵局。所以一定是其他原因导致死锁。

每次发生死锁时,Oracle 都会创建一个跟踪文件,并将新创建的跟踪文件的名称和路径放在 alert.log 文件中。因此,您需要检查创建的 trace(*.trc) 文件的内容,以识别相互阻塞的会话:

*** SESSION ID:(362.24645) 2013-09-04 14:46:05.297
*** CLIENT ID:() 2013-09-04 14:46:05.297
*** SERVICE NAME:(nkrasnov) 2013-09-04 14:46:05.297
*** MODULE NAME:(PL/SQL Developer) 2013-09-04 14:46:05.297
*** CONTAINER ID:(3) 2013-09-04 14:46:05.297

Deadlock graph:
                                          ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name                             process session holds waits  process session holds waits
TX-000B0007-00002730-00000000-00000000        138     362     X            142     441           X
TX-00050011-00000A51-00000000-00000000        142     441     X            138     362           X

session 362: DID 0001-008A-00003BE6 session 441: DID 0001-008E-0000C55F 
session 441: DID 0001-008E-0000C55F session 362: DID 0001-008A-00003BE6 

考虑使用nowait或从 11g子句skip locked选项开始。for update

于 2013-09-04T11:10:14.153 回答