1、Oracle鎖類型
鎖的作用
latch鎖:chain,鏈
LOCK鎖
排他鎖(X)
共享鎖(S)
2、行級鎖:DML語句
事務鎖TX
鎖的結構
事務鎖的加鎖和解鎖過程
只有排他鎖
不影響讀(CR塊)
3、表級鎖:TM
行級排他鎖(Row exclusive)RX鎖
當我們進行DML時,會自動在被更新的表上添加RX鎖,可以執行LOCK命令顯式的在表上添加RX鎖
允許其他事務通過DML語句修改相同表里的其他數據行
允許使用lock命令對表添加RX鎖定
不允許其他事務對表添加X鎖
行級共享鎖(Row Shared,簡稱RS鎖)
select … from for update
共享鎖(Share,簡稱S鎖)
通過lock table in share mode命令添加該S鎖
排他鎖(Exclusive,簡稱X鎖)
通過lock table in exclusive mode命令添加X鎖
共享行級排他鎖(Share Row Exclusive,簡稱SRX鎖)
通過lock table in share row exclusive mode命令添加SRX鎖
4、鎖的兼容性
5、加鎖語句以及鎖的釋放
lock table in [row share][row exclusive][share][share row exclusive][exclusive] mode;
6、鎖相關視圖
v$transaction
XIDUSN表示當前事務使用的回滾段的編號
XIDSLOT說明該事務在回滾段頭部的事務表中對應的記錄編號(也可以叫做槽號)
XIDSQN說明序列號
STATUS說明該事務是否為活動的
v$lock
記錄了session已經獲得的鎖定以及正在請求的鎖定的信息
SID說明session的ID號
TYPE說明鎖定鎖定級別,主要關注TX和TM
LMODE說明已經獲得的鎖定的模式,以數字編碼表示
REQUEST說明正在請求的鎖定的模式,以數字編碼表示
BLOCK說明是否阻止了其他用戶獲得鎖定,大于0說明是,等于0說明否
鎖定模式?? ??? ?鎖定簡稱?? ?編碼數值
Row Exclusive?? ??? ?RX ?? ??? ?3
Row Shared ?? ??? ?RS?? ??? ?2
Share ?? ? ?? ??? ?S ?? ??? ?4
Exclusive ?? ??? ?X ?? ??? ?6
Share Row Exclusive ?? ?SRX ?? ??? ?5
NULL ??? ??? ??? ?N/A ?? ??? ?0或者1
v$enqueue_lock
該視圖中包含的字段以及字段含義與v$lock中的字段一模一樣。
只不過該視圖中只顯示那些申請鎖定,但是無法獲得鎖定的session信息。
其中的記錄按照申請鎖定的時間先后順序排列,先申請鎖定的session排在前面,排在前面的session將會先獲得鎖定。
v$locked_object
記錄了當前已經被鎖定的對象的信息
XIDUSN表示當前事務使用的回滾段的編號
XIDSLOT說明該事務在回滾段頭部的事務表中對應的記錄編號
XIDSQN說明序列號
OBJECT_ID說明當前被鎖定的對象的ID號,可以根據該ID號到dba_objects里查找被鎖定的對象名稱
LOCKED_MODE說明鎖定模式的數字編碼
v$session
記錄了當前session的相關信息
SID表示session的編號
SERIAL#表示序列號
SID和SERIAL#可以認為是v$session的主鍵,它們共同唯一標識一個session
grant select on v_$mystat to hr;
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||‘a‘ where department_id=60;
select xidusn,xidslot,xidsqn,status from v$transaction;
selectsid,type,id1,id2,
decode(lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) request_mode,
blockfromv$lockwhere sid=&sid;
select object_name from dba_objects where object_id=&object_id;
對于TM鎖來說,ID1表示被鎖定的對象的對象ID,ID2始終為0
對于TX鎖來說,ID1表示事務使用的回滾段編號以及在事務表中對應的記錄編號,ID2表示該記錄編號被重用的次數(wrap)
將ID1拆解
select trunc(393249/power(2,16)) as undo_blk#,bitand(393249,to_number(‘ffff‘,‘xxxx‘)) + 0 as slot# from dual;
再次打開一個session
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||‘b‘ where department_id=60;
selectsid, type, id1, id2,
decode(lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) request_mode,
blockfromv$lockwhere sid in(&sid1,&sid2)order by sid;
再次打開一個會話
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||‘c‘ where department_id=60;
查詢v$enqueue_lock來獲得鎖定隊列中的session信息
selectsid,type,
decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) request_modefromv$enqueue_lockwhere sid in(&sid1,&sid2);
select a.sid blocker_sid, a.serial#, a.username asblocker_username, b.type,
decode(b.lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
b.ctimeas time_held,c.sid aswaiter_sid,
decode(c.request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) request_mode,
c.ctime time_waitedfromv$lock b, v$enqueue_lock c, v$session awhere a.sid = b.sid and b.id1= c.id1(+) and b.id2 = c.id2(+) and c.type(+) = ‘TX‘ and b.type = ‘TX‘ and b.block = 1
order by time_held, time_waited;
alter system kill session ‘&sid,&serial‘;
一個事務修改多行,產生一個TX鎖
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||‘a‘ where department_id=60;update departments set department_name=‘unknow‘ where department_id=10;update locations set city=‘unknown‘ where location_id=1100;
selectsid, type, id1, id2,
decode(lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) request_mode,blockfromv$lockwhere sid=&sid;
可以獲得的TX鎖定的總個數由初始化參數transactions決定,而可以獲得的TM鎖定的個數則由初始化參數dml_locks決定
select name, value from v$parameter where name in(‘transactions‘,‘dml_locks‘);
select resource_name as "R_N", current_utilization as "C_U", max_utilization as "M_U", initial_allocation as"I_U"fromv$resource_limitwhere resource_name in(‘transactions‘,‘dml_locks‘);
7、死鎖
兩個session(以A和C來表示),如果A持有C正在申請的鎖定,同時C也持有A正在申請的鎖定時,這時發生死鎖現象。死鎖是典型的“雙輸”情況,如果任其發展,則會出現A和C這兩個session正在執行的事務都無法結束的現象。因此,在Oracle數據庫中,造成死鎖的那個DML語句會被撤銷。死鎖總是由于應用程序設計不合理引起的。
當某個session的事務引起了死鎖時,Oracle會自動將阻塞該事務的其他事務中相應的DML語句撤銷,而阻塞該事務的其他事務中的其他DML語句并沒有撤銷。
session 1
select sid from v$mystat where rownum=1;update employees set last_name=last_name||‘a‘ where employee_id=100
session 2
select sid from v$mystat where rownum=1;update employees set last_name=last_name||‘b‘ where employee_id=101;
session 1
update employees set last_name=last_name||‘c‘ where employee_id=101;
session 2
update employees set last_name=last_name||‘d‘ where employee_id=100;
原文:http://www.cnblogs.com/jyzhao/p/3819381.html