一个自己锁自己的例子

有朋友问我:“一个transaction会自我死锁吗?也就是自己锁死了自己”。

很凑巧,半个月前我刚好帮同事处理过这种自我死锁的情况。

 

我们这里来构造一个自我死锁的例子:

SQL> select sid from v$mystat where rownum<2;

 

       SID

———-

       362

 

SQL> create table t1 (id varchar2(10),amount number(10));

 

Table created

 

SQL> insert in into t1 values(‘cuihua’,100);

 

1 row inserted

 

SQL> commit;

 

Commit complete

 

SQL> select * from t1;

 

ID              AMOUNT

———- ———–

cuihua             100

 

SQL> create procedure p_autonomous is

  2  PRAGMA  AUTONOMOUS_TRANSACTION;

  3  begin

  4    update t1 set amount=102 wholesale mlb jerseys where id=’cuihua’;

  5    commit;

  6  end;

  7  /

 

Procedure created

 

SQL> create procedure p_test is

  2  begin

  3    update t1 set amount=101 where id=’cuihua’;

  4    p_autonomous;

  5 

  6    commit;

  7  end;

  8  /

 

Procedure created

 

现在只要我执行上述存储过程p_test,就会产生自我死锁,如下所示

SQL> exec p_test;

 

begin p_test; end;

 

ORA-00060: deadlock detected while waiting for resource

ORA-06512: at “IPRA.P_AUTONOMOUS”, line 4

ORA-06512: at “IPRA.P_TEST”, line 4

ORA-06512: at line wholesale mlb jerseys 1

 

此时alert log里会显示:

ORA-00060: Deadlock detected. More info in file /u01/app/oracle/admin/ipra/udump/ipra_ora_921828.trc.

 

从上述trace文件里我们可以看到:

Deadlock graph:

                       ———Blocker(s)——–  ———Waiter(s)———

Resource Name          process session holds waits  process session holds waits

TX-00060005-00016466        33     362     X             33     362           X

session 362: DID 0001-0021-000001F4     session 362: DID 0001-0021-000001F4

 

也就是说这里的Blockersession 362Waiter也是session 362,典型的自己锁死了自己

 

不知道我为什么要这样构造的朋友们看了如下这样一段话就什么都明白了:

The Oracle server provides the ability to temporarily suspend a current transaction and begin another. This second transaction is known as an autonomous transaction and runs independently of its parent. The autonomous or child transaction can commit or roll back as applicable, with the execution of the parent transaction being resumed upon its completion.

The parent may then perform further operations and commit or roll back without affecting the 深入解析DEPENDENCY$对象的恢复 outcome of any operations performed within the child. The child transaction does not inherit transaction context (that is, SET TRANSACTION statements). The transactions are organized as a stack: something Only the “top” transaction is accessible at any given time. Once completed, the autonomous transaction is “popped” and the calling transaction is again visible. The limit to the number of suspended transactions Full is governed by the initialization parameter TRANSACTIONS.

The Oracle server uses similar functionality internally in recursive transactions.

Transactions must be explicitly committed or rolled back or an error ORA-6519 is cheap jerseys signaled when attempting to return from the autonomous block.

A deadlock situation may occur where a called and calling transaction deadlock; — this is not prevented, but is wholesale mlb jerseys signaled by an error unique to this situation. The application developer is responsible for avoiding this situation.