1.數據庫鎖的概念
爲了確保併發用戶在存取同一數據庫對象時的正確性(即無丟失修改、可重複讀、不讀
“髒”數據),數據庫中引入了鎖機制。基本的鎖類型有兩種:排它鎖(Exclusive locks 記
爲X 鎖)和共享鎖(Share locks記爲 S鎖)。
排它鎖:若事務T對數據D加X鎖,則其它任何事務都不能再對D加任何類型的鎖,
直至T 釋放D 上的X 鎖;一般要求在修改數據前要向該數據加排它鎖,所以排它鎖又稱爲
寫鎖。
共享鎖:若事務T對數據D加S 鎖,則其它事務只能對D加 S鎖,而不能加X 鎖,直
至 T 釋放 D 上的 S 鎖;一般要求在讀取數據前要向該數據加共享鎖,所以共享鎖又稱爲讀
鎖。
2.Oracle多粒度封鎖機制介紹
根據保護對象的不同,Oracle數據庫鎖可以分爲以下幾大類:
(1) DML lock(data locks,數據鎖):用於保護數據的完整性;
(2) DDL lock(dictionary locks,字典鎖):用於保護數據庫對象的結構(例如表、視圖、索
引的結構定義);
(3) internal locks 和 l a t c h es(內部鎖與閂):保護內部數據庫結構;
(4) distributed locks(分佈式鎖):用於OPS(並行服務器)中;
(5) PCM locks(並行高速緩存管理鎖):用於OPS(並行服務器)中。
本文主要討論DML(也可稱爲data locks,數據鎖)鎖。從封鎖粒度(封鎖對象的大小)
的角度看,Oracle DML鎖共有兩個層次,即行級鎖和表級鎖。
2.1 Oracle 的 TX 鎖(行級鎖、事務鎖)
許多對Oracle不太瞭解的技術人員可能會以爲每一個 TX鎖代表一條被封鎖的數據行,
其實不然。 TX的本義是Transaction (事務),當一個事務第一次執行數據更改(Insert、 Update、
Delete)或使用SELECT… FOR UPDATE 語句進行查詢時,它即獲得一個TX(事務)鎖,
直至該事務結束(執行COMMIT 或ROLLBACK操作)時,該鎖才被釋放。所以,一個TX
鎖,可以對應多個被該事務鎖定的數據行。
在 Oracle 的每行數據上,都有一個標誌位來表示該行數據是否被鎖定。Oracle 不象其
它一些 DBMS(數據庫管理系統)那樣,建立一個鏈表來維護每一行被加鎖的數據,這樣
就大大減小了行級鎖的維護開銷,也在很大程度上避免了其它數據庫系統使用行級封鎖時經
常發生的鎖數量不夠的情況。數據行上的鎖標誌一旦被置位,就表明該行數據被加 X 鎖,
Oracle在數據行上沒有 S鎖。 2.2 TM鎖(表級鎖)
2.2.1 意向鎖的引出
表是由行組成的,當我們向某個表加鎖時,一方面需要檢查該鎖的申請是否與原有的表
級鎖相容;另一方面,還要檢查該鎖是否與表中的每一行上的鎖相容。比如一個事務要在一
個表上加 S 鎖,如果表中的一行已被另外的事務加了 X 鎖,那麼該鎖的申請也應被阻塞。
如果表中的數據很多,逐行檢查鎖標誌的開銷將很大,系統的性能將會受到影響。爲了解決
這個問題,可以在表級引入新的鎖類型來表示其所屬行的加鎖情況,這就引出了“意向鎖”
的概念。
意向鎖的含義是如果對一個結點加意向鎖,則說明該結點的下層結點正在被加鎖;對任
一結點加鎖時,必須先對它的上層結點加意向鎖。如:對錶中的任一行加鎖時,必須先對它
所在的表加意向鎖,然後再對該行加鎖。這樣一來,事務對錶加鎖時,就不再需要檢查表中
每行記錄的鎖標誌位了,系統效率得以大大提高。
2.2.2 意向鎖的類型
由兩種基本的鎖類型(S鎖、X 鎖),可以自然地派生出兩種意向鎖:
意向共享鎖(Intent Share Lock,簡稱 IS 鎖):如果要對一個數據庫對象加S鎖,首先
要對其上級結點加IS 鎖,表示它的後裔結點擬(意向)加 S鎖;
意向排它鎖(Intent Exclusive Lock,簡稱 IX 鎖):如果要對一個數據庫對象加X 鎖,
首先要對其上級結點加 IX鎖,表示它的後裔結點擬(意向)加X 鎖。
另外,基本的鎖類型(S、X)與意向鎖類型(IS、IX)之間還可以組合出新的鎖類型,
理論上可以組合出4種,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不難看出,實際上只
有 S+IX 有新的意義,其它三種組合都沒有使鎖的強度得到提高(即:S+IS=S,X+IS=X,
X+IX=X,這裏的“=”指鎖的強度相同)。所謂鎖的強度是指對其它鎖的排斥程度。
這樣我們又可以引入一種新的鎖的類型
共享意向排它鎖(Shared Intent Exclusive Lock,簡稱 SIX 鎖) :如果對一個數據庫對象
加 SIX 鎖,表示對它加 S 鎖,再加 IX 鎖,即 SIX=S+IX。例如:事務對某個表加 SIX 鎖,
則表示該事務要讀整個表(所以要對該表加S 鎖),同時會更新個別行(所以要對該表加 IX
鎖)。
這樣數據庫對象上所加的鎖類型就可能有5 種:即S、X、IS、IX、SIX。
具有意向鎖的多粒度封鎖方法中任意事務 T 要對一個數據庫對象加鎖,必須先對它的
上層結點加意向鎖。申請封鎖時應按自上而下的次序進行;釋放封鎖時則應按自下而上的次
序進行;具有意向鎖的多粒度封鎖方法提高了系統的併發度,減少了加鎖和解鎖的開銷。
2.2.3 Oracle 的 TM 鎖(表級鎖)
Oracle的 DML鎖(數據鎖)正是採用了上面提到的多粒度封鎖方法,其行級鎖雖然只
有一種(即X鎖),但其 TM鎖(表級鎖)類型共有5種,分別稱爲共享鎖(S鎖)、排它鎖
(X 鎖)、行級共享鎖(RS 鎖)、行級排它鎖(RX 鎖)、共享行級排它鎖(SRX 鎖),與上面提到的S、X、IS、IX、SIX 相對應。需要注意的是,由於Oracle在行級只提供X鎖,所
以與RS鎖(通過SELECT … FOR UPDATE語句獲得)對應的行級鎖也是X鎖(但是該行
數據實際上還沒有被修改),這與理論上的IS 鎖是有區別的。
下表爲Oracle數據庫TM鎖的相容矩陣(Y=Yes,表示相容的請求; N=No,表示不相
容的請求;-表示沒有加鎖請求):
T2
T1
S X RS RX SRX -
S Y N Y N N Y
X N N N N N Y
RS Y N Y Y Y Y
RX N N Y Y N Y
SRX N N Y N N Y
- Y Y Y Y Y Y
表一:Oracle 數據庫 TM 鎖的相容矩陣
一方面,當Oracle 執行SELECT…FOR UPDATE、 INSERT、 UPDATE、 DELETE等 DML
語句時,系統自動在所要操作的表上申請表級RS鎖(SELECT…FOR UPDATE)或 RX鎖
(INSERT、UPDATE、DELETE),當表級鎖獲得後,系統再自動申請 TX 鎖,並將實際鎖
定的數據行的鎖標誌位置位(指向該TX鎖);另一方面,程序或操作人員也可以通過 LOCK
TABLE 語句來指定獲得某種類型的TM鎖。下表總結了 Oracle中各 SQL語句產生 TM鎖的
情況:
SQL語句 表鎖模式 允許的鎖模式
Select * from table_name…… 無 RS、RX、S、SRX、X
Insert into table_name…… RX RS、RX
Update table_name…… RX RS、RX
Delete from table_name…… RX RS、RX
Select * from t