1. 程式人生 > >鎖的種類,阻塞,死鎖產生與解決辦法。

鎖的種類,阻塞,死鎖產生與解決辦法。

TM鎖的種類: 

 TM鎖幾種模式的互斥關係:

阻塞

定義:
當一個會話保持另一個會話正在請求的資源上的鎖定時,就會發生阻塞。被阻塞的會話將一直掛起,直到持有鎖的會話放棄鎖定的資源為止。4個常見的dml語句會產生阻塞
INSERT
UPDATE
DELETE
SELECT…FOR UPDATE

——————————————————————————————————————————————————————————————

update 的阻塞     試驗:

1.    獲得會話sid 

SQL> select sid from v$mystat where rownum=1;    (首先update的會話sid)

SID
----------
1

SQL> select sid from v$mystat where rownum=1;     (隨後update的會話sid)

SID
----------
39

2.   操作表

SQL> select * from andy;     (檢視操作表)

ID
----------
1

SQL> update andy set id=2 where id=1;     (首先,會話sid為1的update)

1 row updated.

SQL> update andy set id=2 where id=1;      (隨後,會話sid為39的update,執行後,發現被阻塞)

3.   檢視會話鎖衝突

SQL> select sid,type,lmode,id1,id2,request,block from v$lock where type in('TM','TX') order by 1,2;

SID         TY  LMODE       ID1         ID2         REQUEST BLOCK
---------- --  ---------- ---------- ---------- ---------- ----------
1             TM       3       79729         0             0             0
1             TX       6       131072       1276        0             1
39           TM       3       79729         0             0             0
39           TX       0       131072       1276        6             0

解釋說明:

SID:表示會話sid。

TY:表示鎖的型別。

ID1:在TM一行中表示的是被修改表的標識(object_id)。

ID1:在TX一行中表示以十進位制數值表示該事務所佔用的回滾段號與該事務在該回滾段的事務表(Transaction table)中所佔用的槽號(slot number,可理解為記錄號)。其組成形式為: 0xRRRRSS 如:  1             TX       6       131072       1276        0             1

REQUEST:0表示的是已經獲得鎖。非0表示被阻塞,請求獲得鎖。 如:sid為1的會話,先update andy set id=2 where id=1;獲得該行的TX鎖,但為提交。然後sid為39的會話,再次andy set id=2 where id=1;請求獲得該行的TX鎖,但是該行TX鎖被sid為1的會話佔用,所以未獲得該說,被阻塞,只能等待(sid為1提交與自己回滾)。

BLOCK:表示該鎖是否阻塞了其他鎖。 數字幾代表阻塞了幾

--  驗證 TM一行中表示的是被修改表的標識(object_id)。(確實如此)

SQL> select object_name from dba_objects where object_id=79729;

OBJECT_NAME
--------------------------------------------------------------------------------
ANDY

至此,阻塞試驗完畢。

查詢會話之間鎖等待的關係

select a.sid holdsid,b.sid waitsid,a.type ,a.id1,a.id2,a.ctime from v$lock a,v$lock b
where a.id1=b.id1 and a.id2=b.id2 and a.block = 1 and b.block = 0 ;

HOLDSID WAITSID TY ID1 ID2 CTIME
---------- ---------- -- ---------- ---------- ----------
1 39 TX 458777 1066 503
1 51 TX 458777 1066 503

查被阻塞的會話
select * from v$lock where lmode=0 and type in ('TM','TX');

——————————————————————————————————————————————————————————

死鎖-deadlock

定義:當兩個使用者希望持有對方的資源時就會發生死鎖.
即兩個使用者互相等待對方釋放資源時,oracle認定為產生了死鎖,在這種情況下,將以犧牲一個使用者作為代價,另一個使用者繼續執行,犧牲的使用者的事務將回滾.
例子:
1:使用者1對A表進行Update,沒有提交。
2:使用者2對B表進行Update,沒有提交。
此時雙反不存在資源共享的問題。
3:如果使用者2此時對A表作update,則會發生阻塞,需要等到使用者一的事物結束。
4:如果此時使用者1又對B表作update,則產生死鎖。此時Oracle會選擇其中一個使用者進行會滾,使另一個使用者繼續執行操作。
起因:
Oracle的死鎖問題實際上很少見,如果發生,基本上都是不正確的程式設計造成的,經過調整後,基本上都會避免死鎖的發生。

死鎖試驗:

SQL> select * from andy;

ID
----------
3
2

SQL> delete andy where id=2;    (會話1)

1 row deleted.

SQL> delete andy where id=3;     (會話2)

1 row deleted.

SQL> delete andy where id=3;      (會話1)
delete andy where id=3
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

SQL> delete andy where id=2;       (會話2,阻塞狀態)

死鎖產生後,處理辦法:

1)執行下面SQL,先檢視哪些表被鎖住了:
>select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id;

2)檢視引起死鎖的會話
>select b.username,b.sid,b.serial#,logon_time 
18:09:40 2 from v$locked_object a,v$session b
18:09:40 3 where a.session_id = b.sid order by b.logon_time;

3)檢視被阻塞的會話
>select * from dba_waiters;

4)可以提交或回滾阻塞的話,釋放鎖或者殺掉ORACLE程序:
ALTER SYSTEM KILL SESSION 'SID,SERIAL#'; 
說明:
如果殺掉所有死鎖相關的會話,則所有會話的事務回滾,相當於事務都為未執行。
如果殺掉報ORA-00060: deadlock detected while waiting for resource的會話,阻塞會話commit,阻塞會話將完成該會話的所有事務。
如果殺掉被阻塞的會話,報ORA-00060會話commit,則完成的事務是未產生死鎖之前的事務。
如果報ORA-00060: deadlock detected while waiting for resource的會話進行rollback,阻塞會話commit,阻塞會話將完成該會話所有事務。

如果系統總是出現死鎖:

則 trace,找到sql,分析業務,修改sql,避免死鎖。   

ok,結束。 轉載請標明出處。