1. 程式人生 > >oracle死鎖語句查詢

oracle死鎖語句查詢

造成死鎖的原因就是多個執行緒或程序對同一個資源的爭搶或相互依賴。這裡列舉一個對同一個資源的爭搶造成死鎖的例項。

Oracle 10g, PL/SQL version 9.2

  1. CREATETABLE testLock(  
  2. ID NUMBER,  
  3. test VARCHAR(100)  
  4. )  
  5. COMMIT
  6. INSERTINTO testLock VALUES(1,'test1');  
  7. INSERTINTO testLock VALUES(2,'test2');  
  8. COMMIT;  
  1. SELECT * FROM testLock   
  2.         ID TEST  
  3. ---------- ----------------------------------
  4.          1 test1  
  5.          2 test2  

死鎖現象的重現:

1)在sql 視窗 執行:SELECT * FROM testLock FOR UPDATE; -- 加行級鎖 並對內容進行修改,不要提交

2)另開一個command視窗,執行:delete from testLock WHERE ID=1;

此時發生死鎖(注意此時要另開一個視窗,不然會提示:POST THE CHANGE RECORD TO THE DATABASE. 點yes 後強制commit):

3)死鎖檢視:

  1. <p> </p><p>  
  2. SQL>  select s.username,l.object_id, l.session_id,s.serial#, s.lockwait,s.status,s.machine,s.program from v$session s,v$locked_object l where s.sid = l.session_id;</p><p>USERNAME    SESSION_ID  SERIAL#    LOCKWAIT STATUS   MACHINE                 PROGRAM  
  3. ----------  ----------  ---------- -------- -------- ----------------------  ------------
  4. SYS         146         104                 INACTIVE WORKGROUP\J-THINK       PLSQLDev.exe  
  5. SYS         144         145        20834474 ACTIVE   WORKGROUP\J-THINK       PLSQLDev.exe</p><p> </p>  

欄位說明:
Username:死鎖語句所用的資料庫使用者;
SID: session identifier, session 標示符,session 是通訊雙方從開始通訊到通訊結束期間的一個上下文。
SERIAL#: sid 會重用,但是同一個sid被重用時,serial#會增加,不會重複。越後面執行的sql語句serial#的越大
Lockwait:可以通過這個欄位查詢出當前正在執行的sql語句已經等待的時間。
Status:用來判斷session狀態。Active:正執行SQL語句,就是被死鎖住的語句,無法繼續執行下去。Inactive:等待操作,未提交的操作。Killed:被標註為刪除。

其中
Machine: 死鎖語句所在的機器。
Program: 產生死鎖的語句主要來自哪個應用程式。

4)檢視引起死鎖的語句:

  1. SQL>  select sql_text from v$sql where hash_value in   (select sql_hash_value from v$session where sid in  (select session_id from v$locked_object));  
  2. SQL_TEXT  
  3. ------------------------------------------------------------
  1. deletefrom testLock where  ID = 1  


5)死鎖的處理:

  1. SQL> alter system kill session '144,145';  
  2. System altered  
  3. Executed in 1.061 seconds  

session中兩個引數分別是session_id和serial#


此時在執行delete語句的窗口出現:

  1. SQL> deletefrom testLock where  ID = 1;  
  2. deletefrom testLock where  ID = 1  
  3. ORA-00028: 您的會話己被終止  


再檢視一下死鎖,會發現已經沒有stauts為active的記錄了:

  1. SQL>  select s.username, l.session_id,s.serial#, s.lockwait,s.status,s.machine,s.program from v$session s,v$locked_object l where s.sid = l.session_id;  
  2. USERNAME                 SESSION_ID SERIAL#  LOCKWAIT STATUS   MACHINE             PROGRAM  
  3. ------------- ---------- ---------- -------- -------- ---------------------------  ----------------
  1. SYS                      146        104               INACTIVE WORKGROUP\J-THINK   PLSQLDev.exe  
  2. Executed in 0.032 seconds  


發生死鎖餓語句已經被終止。


引用: