Oracle-11g中的併發控制(2012/11/16)

1 事務基礎

在DB中,可能出現如下3種現象

髒讀

在事務中,讀到了其它事務沒有提交的記錄

不可重複讀

在事務中,即使查詢條件相同,下次返回的記錄與上次返回記錄不一樣,不一樣體現在記錄被修改或記錄被刪除

幻影讀

在事務中,即使查詢條件相同,下次返回的記錄與上次返回記錄不一樣,不一樣體現在新增加了記錄。

SQL92規定的事務隔離級別如下表。


oracle支持3種事務隔離級別:read-only/readcommitted/serializable。其中read-only不屬於SQL92,readcommitted是oracle的默認隔離級別。

2 oracle中併發控制

2.1 多版本併發控制

在undo segment中保留了歷史數據,也就是說記錄可能有多個版本,版本用SCN(systemchange manage)來識別。SCN是事務提交後系統爲之分配的一個全局唯一的事務ID。undo segment中的數據有3種功能:便於事務回滾,提供讀一致性,支持flashback。

查詢語句被啓動的同時獲取當前的SCN,DB只會返回SCN小於當前SCN的記錄。多版本併發控制技術使得讀不阻塞寫,寫不阻塞讀,從而大大的提高了系統的併發性。【多個版本的數據是存儲在undo segment中】


2.2 oracle支持的讀一致性

oracle支持兩個級別的讀一致性。語句級讀一致性和事務級讀一致性。oracle天生支持語句級讀一致性,只有隔離級別在serializable時支持事務級讀一致性。

●語句級讀一致性

讀到的數據集和查詢啓動時的結果集是一樣的。也就是說,不存在髒讀,也不會讀到查詢啓動之後其它事務提交的數據(包括update/delete/insert)。

●事務級讀一致性

概念和serializable是一致的。

2.3 oracle中的鎖

2.3.1 上鎖的時機以及持續時間

上鎖發生在語句級別,解鎖發生在事務級別。即提交事務或回滾時釋放鎖,事務開始時不會獲取鎖,而是在執行過程中,若語句需要纔會上鎖。

2.3.2 鎖的類型

●DML鎖即data鎖,保護數據

●DDL鎖即dictionary鎖,保護對象的定義

●內部鎖和latch,保護內部的數據結構,比如數據文件

2.3.3 DML鎖

2.3.3.1行鎖

當事務需要修改某個記錄時,需要獲取這個記錄對應的行鎖。在執行update/delete/insert/select…for udpate時,獲取行鎖。

實際上,一個行鎖可能對應多個記錄。即行鎖是一個粗粒度的鎖,其開銷不大,所以系統不會控制單個事務被上鎖的記錄的數量。

【理解】其實oracle不需要細化到一個記錄的鎖。比如,T1事務現在需要修改記錄R,但是此時記錄R已經被事務T2上鎖,T1需要等待T2被提交或回滾是才能操作記錄R,T2被被提交或回滾涉及到的記錄是所有被T2修改過的記錄。

2.3.3.2表鎖

DDL和DML都需要表鎖。在DML操作中需要獲取表鎖的語句有insert/delete/update/select…forupdate/lock table.

表是由行組成的,當我們向某個表加鎖時,一方面需要檢查該鎖的申請是否與原有的表級鎖相容;另一方面,還要檢查該鎖是否與表中的每一行上的鎖相容。比如一個事務要在一個表上加 S 鎖,如果表中的一行已被另外的事務加了 X 鎖,那麼該鎖的申請也應被阻塞。如果表中的數據很多,逐行檢查鎖標誌的開銷將很大,系統的性能將會受到影響。爲了解決這個問題,可以在表級引入新的鎖類型來表示其所屬行的加鎖情況,這就引出了“意向鎖”的概念。意向鎖的含義是如果對一個結點加意向鎖,則說明該結點的下層結點正在被加鎖;對任一結點加鎖時,必須先對它的上層結點加意向鎖。如:對錶中的任一行加鎖時,必須先對它所在的表加意向鎖,然後再對該行加鎖。這樣一來,事務對錶加鎖時,就不再需要檢查表中每行記錄的鎖標誌位了,系統效率得以大大提高。

 鎖有兩種基本的鎖類型(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,這裏的“=”指鎖的強度相同)。所謂鎖的強度是指對其它鎖的排斥程度。

 這樣我們又可以引入一種新的鎖的類型共享意向排它鎖(SharedIntent Exclusive Lock,簡稱 SIX 鎖) :如果對一個數據庫對象加 SIX 鎖,表示對它加 S 鎖,再加IX 鎖,即 SIX=S+IX。例如:事務對某個表加 SIX 鎖,則表示該事務要讀整個表(所以要對該表加S 鎖),同時會更新個別行(所以要對該表加 IX

鎖)。這樣數據庫對象上所加的鎖類型就可能有5 種:即S、X、IS、IX、SIX。

具有意向鎖的多粒度封鎖方法中任意事務 T 要對一個數據庫對象加鎖,必須先對它的上層結點加意向鎖。申請封鎖時應按自上而下的次序進行;釋放封鎖時則應按自下而上的次序進行;具有意向鎖的多粒度封鎖方法提高了系統的併發度,減少了加鎖和解鎖的開銷。

 Oracle的 DML鎖(數據鎖)正是採用了上面提到的多粒度封鎖方法,其行級鎖雖然只有一種(即X鎖),但其 TM鎖(表級鎖)類型共有5種,分別稱爲共享鎖(S鎖)、排它鎖(X 鎖)、行級共享鎖(RS鎖)、行級排它鎖(RX 鎖)、共享行級排它鎖(SRX 鎖),與上面提到的S、X、IS、IX、SIX 相對應。

 各個鎖的意義如下:【個人理解,有待驗證】

RS鎖

表示事務要讀取表的少量記錄

RX鎖

表示事務要修改表的少量記錄

S鎖

表示事務要讀取表的絕大部分記錄

SRX鎖

表示事務要讀取表的絕大部分記錄

並且需要修改少量記錄

X鎖

表示事務要修改表的絕大部分記錄

或者需要修改表的定義

 各個粒度的鎖的相容性如下:



【理解】

進行DML操作只會獲取RX粒度的表鎖,由於RX之間是相容和的,所以DML之間在表鎖層次是不會相互阻塞的。進行DDL操作時獲取X鎖(個人猜測)。因爲讀操作不需枷鎖,爲什麼還需要S/RS/SRX粒度的表鎖?答案是爲用戶自己控制並行性提供條件

 2.3.4 DDL鎖

用於保護對象的定義,用戶不能顯示的獲得。事務會對其涉及到對象添加DDL鎖,從而避免在操作對象數據的過程中對象被刪除或定義被修改。DDL鎖分爲3個類型

Exclusive DDL lock

DDL需要修改對象的定義時需要獲取此鎖。在這種情況下,DDL也會獲取表鎖(應該是X鎖)。

Shared DDL lock

比如在create procdure過程中需要此鎖

Breakable DDL lock

在shared SQL area中,存儲了已經解析並優化過的SQL語句,這些SQL語句是和對象(比如table/view)相關聯,若關聯的對象的定義改變,那麼在shared SQL area對應的SQL語句就失效了。

在對象的定義發生變化後,Breakable DDL lock用來通知shared sql area刪除對應的SQL項。

 2.3.5 內部鎖和latch

latch是輕量級鎖。用於保護SGA共享的數據結構。

2.3.10 鎖轉換和鎖提升(Data LockConversion Versus Lock Escalation)

鎖轉換

改變鎖的嚴格程度,比如把 S鎖轉換爲X鎖

鎖升級

改變鎖的粒度,比如把行鎖變爲表鎖

 因爲鎖升級大大的提升了死鎖的概率,所以oracle從來不會進行鎖升級。

2.3.11 死鎖

oracle會自動檢測死鎖,發生死鎖後,回滾其中的一個事務的當前語句。應用如何避免死鎖?各個事務按照相同的順序處理數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章