自相矛盾:一個程序可以自成死鎖麼?
阿新 • • 發佈:2022-05-02
崔華,網名 dbsnake
Oracle ACE Director,ACOUG 核心專家
編輯手記:感謝崔華授權我們獨家轉載其精品文章,也歡迎大家向“Oracle”社群投稿。在新年前,輕鬆一點,看看崔華這篇小文,通過一個簡單的例子,理解Oracle的自制事務、死鎖,建議大家動手去測試、嘗試,從而從中學到更多的知識。
有朋友問我:“一個transaction會自我死鎖嗎?也就是自己鎖死了自己”。
很湊巧,半個月前我剛好幫同事處理過這種自我死鎖的情況。
我們這裡來構造一個自我死鎖的例子:
select sid from v$mystat where rownum<2; SID ———- 362 SQL> create table t1 (id varchar2(10), amount number(10)); Table created SQL> insert 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 5 where id='cuihua'; 6 commit; 7 end; 8 / Procedure created SQL> create procedure p_test is 2 begin 3 update t1 set amount=101 where id='cuihua'; 4 p_autonomous; 5 commit; 6 end; 7 / Procedure created
現在只要我執行上述儲存過程p_test,就會產生自我死鎖,如下所示:
此時alert log裡會顯示:
ORA-00060: Deadlock detected.
More info in file /u01/app/oracle/admin/ipra/udump/ipra_ora_921828.trc.
從上述trace檔案裡我們可以看到:
也就是說這裡的Blocker是session 362,Waiter也是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 rollback 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 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: 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 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 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 signaled by an error unique to this situation. The application developer is responsible for avoiding this situation.
近期文章