Oracle鎖2:DML操作和鎖
來源:程序員人生 發布時間:2015-01-23 08:50:06 閱讀次數:4392次
Oracle為DML操作自動獲得行鎖和表鎖,操作的類型決定了鎖的行動,下面對DML操作鎖的情況作了1個匯總:
SQL Statement |
Row Locks |
Table Lock Mode |
RS |
RX |
S |
SRX |
X |
SELECT ... FROM table ... |
―― |
none |
Y |
Y |
Y |
Y |
Y |
INSERT INTO table ... |
Yes |
SX |
Y |
Y |
N |
N |
N |
UPDATE table ... |
Yes |
SX |
Y(注) |
Y(注) |
N |
N |
N |
MERGE INTO table ... |
Yes |
SX |
Y |
Y |
N |
N |
N |
DELETE FROM table ... |
Yes |
SX |
Y(注) |
Y(注) |
N |
N |
N |
SELECT ... FROM table FOR UPDATE OF ... |
Yes |
SX |
Y(注) |
Y(注) |
N |
N |
N |
LOCK TABLE table IN ... |
―― |
|
|
|
|
|
|
ROW SHARE MODE |
|
SS |
Y |
Y |
Y |
Y |
N |
ROW EXCLUSIVE MODE |
|
SX |
Y |
Y |
N |
N |
N |
SHARE MODE |
|
S |
Y |
N |
Y |
N |
N |
SHARE ROW EXCLUSIVE MODE |
|
SSX |
Y |
N |
N |
N |
N |
EXCLUSIVE MODE |
|
X |
N |
N |
N |
N |
N |
注:如果另外一個事務和當前事務出現行沖突,則需要等待
下面論述當行被查詢和修改時會觸及到的鎖。
當行被查詢時的鎖
1個查詢可以直接通過SELECT查詢數據,或其它語句間接的查詢數據,如:INSERT、MERGE、UPDATE和DELETE,其中只有INSERT操作不是一定會觸及到查詢的。由于查詢僅讀數據,因此他們被其它DML語句干涉的可能性是最小的。
如果查詢沒有FOR UPDATE子句,則查詢時:
1)查詢不要求數據鎖,因此,其它事務能查詢和更新正在被查詢的數據;
2)查詢沒必要等待任何數據鎖被釋放,因此,查詢總是能履行。1個例外是查詢必須等待散布式事務的1些特定的數據鎖。
當行被修改時的鎖
1些
數據庫使用1個內存中的列表來保護鎖,但
Oracle數據庫存儲鎖信息在數據塊中,信息包括了被鎖的行,每一個行鎖僅影響1行數據。
Oracle數據庫為行鎖的獲得使用了1個隊列機制,如果1個事務要求1個行鎖,并且行未被鎖,那末事務獲得行的數據塊的1個鎖,事務本身會在數據塊頭的interested transaction list(ITL)區域放1個條目,被事務修改的每行都指向ITL中存儲的事務ID的1個拷貝,因此,被單個事務修改的在同1塊中的100行數據會要求100個行鎖,但是所有100行都援用同1個事務ID。
當事務結束時,事務ID保存在數據塊頭的ITL區域中。如果1個新的事物想修改1行,那末它使用事務ID判斷該鎖是不是是激活的,如果鎖是激活的,那末新事務的session會要求在鎖被釋放時被通知,否則,新事務獲得鎖。
INSERT、UPDATE、DELETE和SELECT ... FOR UPDATE將滿足:
1)使用這些DML操作的事務將在修改的行上要求排它行鎖,因此,其它事務不能更新或刪除鎖定的行,直到事務commit或roll back;
2)除行鎖,使用這些DML操作的事務最少需要要求1個子排它表鎖(subexclusive table lock,SX)。如果事務已具有了1個S、SRX或X表鎖(比SX鎖有更強的限制),那末SX鎖不被需要;如果事務已具有了1個SS鎖,那末
Oracle數據庫自動轉換SS鎖到SX鎖;
3)除非觸及的行被修改,事務不會對任何子查詢或隱含的子查詢觸及的行加行鎖;例以下面的update操作,使用那個了1個子查詢(括號中的部份)和隱含子查詢(WHERE a > 5):
UPDATE t SET x = ( SELECT y FROM t2 WHERE t2.z = t.z ) WHERE a > 5;
事務將不會對子查詢(SELECT y FROM t2 WHERE t2.z = t.z)觸及的行加鎖。
4)在同1個事務中,1個查詢能看到先前的DML語句修改的行,但不能看到其它事務未提交的改變。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈