天天看點

ORA-60死鎖的實驗

ORA-60死鎖的實驗

建立表:

SQL> create table tbl_ora_60 (

     id number(5),

     name varchar2(5)

     );

SQL> insert into tbl_ora_60 values(1, 'a');

1 row created.

SQL> insert into tbl_ora_60 values(2, 'b');

SQL> commit;

Commit complete.

SQL> select * from tbl_ora_60;

        ID NAME

---------- -----

         1 a

         2 b

實驗開始

Session1:

SQL> update tbl_ora_60 set name='c' where id=1;

1 row updated.

Session2:

SQL> update tbl_ora_60 set name='d' where id=2;

SQL> update tbl_ora_60 set name='e' where id=2;

hang住

SQL> update tbl_ora_60 set name='f' where id=1;

此時,Session1:

update tbl_ora_60 set name='e' where id=2

       *

ERROR at line 1:

ORA-00060: deadlock detected while waiting for resource

說明:

Session1                                            Session2

擷取id=1的資源鎖

                                                        擷取id=2的資源鎖

等待id=2的資源鎖

                                                        等待id=1的資源鎖

id=2的SQL報ORA-60,自動rollback

1、因為id=2的資源鎖是Session2先擷取的,是以Oracle會自動rollback産生死鎖時後需要資源鎖的SQL,Session1的更新id=2操作被rollback。

2、從中可以發現,真正報ORA-60錯誤的SQL擷取的資源(此例中id=2),并不是觸發死鎖産生的那個資源(此例中id=1),此例用的是同一個表的不同行,對不同表的相同行也如此,也可以解釋之前夜維出現ORA-60時顯示的SQL之間表是不同的原因,因為夜維執行的某個表更新與目前應用執行的某個表更新之間存在互鎖的情況,是以可能導緻夜維SQL報ORA-60或應用報ORA-60的錯誤。

         1 c

說明:此處可以證明産生報錯後,Oracle自動執行的rollback操作是基于單條SQL,不是整個事務的,是以這裡隻有id=2的記錄被rollback,id=1的執行仍正常。

繼續,Session1:

隻有id=1更新成功。

         1 f

         2 d

id=1和id=2都更新成功,但未COMMIT。

因Session2執行COMMIT,送出更新,此處顯示與Session執行相同。