程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> Oracle鎖2:DML操作和鎖

Oracle鎖2:DML操作和鎖

編輯:Oracle教程

Oracle鎖2:DML操作和鎖


Oracle為DML操作自動獲取行鎖和表鎖,操作的類型決定了鎖的行為,下面對DML操作鎖的情況作了一個匯總:

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 tableFORUPDATEOF ... Yes SX Y(注) Y(注) N N N LOCK TABLE tableIN ... —— 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

注:如果另一個事務和當前事務出現行沖突,則需要等待

下面闡述當行被查詢和修改時會涉及到的鎖。

當行被查詢時的鎖

一個查詢可以直接通過SELECT查詢數據,或者其它語句間接的查詢數據,如:INSERT、MERGE、UPDATE和DELETE,其中只有INSERT操作不是必定會涉及到查詢的。因為查詢僅讀數據,因此他們被其它DML語句干涉的可能性是最小的。
如果查詢沒有FOR UPDATE子句,則查詢時:
1)查詢不要求數據鎖,因此,其它事務能查詢和更新正在被查詢的數據;
2)查詢不必等待任何數據鎖被釋放,因此,查詢總是能執行。一個例外是查詢必須等待分布式事務的一些特定的數據鎖。

當行被修改時的鎖

一些數據庫使用一個內存中的列表來維護鎖,但Oracle數據庫存儲鎖信息在數據塊中,信息包含了被鎖的行,每個行鎖僅影響一行數據。
Oracle數據庫為行鎖的獲取使用了一個隊列機制,如果一個事務請求一個行鎖,並且行未被鎖,那麼事務獲取行的數據塊的一個鎖,事務自身會在數據塊頭的interested transaction list(ITL)區域放一個條目,被事務修改的每一行都指向ITL中存儲的事務ID的一個拷貝,因此,被單個事務修改的在同一塊中的100行數據會要求100個行鎖,但是所有100行都引用同一個事務ID。
當事務結束時,事務ID保留在數據塊頭的ITL區域中。如果一個新的事物想修改一行,那麼它使用事務ID判斷該鎖是否是激活的,如果鎖是激活的,那麼新事務的session會請求在鎖被釋放時被通知,否則,新事務獲取鎖。
INSERT、UPDATE、DELETE和SELECT ... FOR UPDATE將滿足:
1)使用這些DML操作的事務將在修改的行上請求排它行鎖,因此,其它事務不能更新或者刪除鎖定的行,直到事務commit或者roll back;
2)除了行鎖,使用這些DML操作的事務至少需要請求一個子排它表鎖(subexclusive table lock,SX)。如果事務已經擁有了一個S、SRX或者X表鎖(比SX鎖有更強的限制),那麼SX鎖不被需要;如果事務已經擁有了一個SS鎖,那麼Oracle數據庫自動轉換SS鎖到SX鎖;
3)除非涉及的行被修改,事務不會對任何子查詢或者隱含的子查詢涉及的行加行鎖;例如下面的update操作,使用那個了一個子查詢(括號中的部分)和隱含子查詢(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)在同一個事務中,一個查詢能看到先前的DML語句修改的行,但不能看到其它事務未提交的改變。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved