??? 相比較Oracle來說,DB2的鎖機制麻煩了很多,而且這個麻煩帶來的不是性能的上升而是下降,
不過如果細致了解的話,只能感慨不愧是數據庫理論誕生的公司,在實現數據庫理論上比Oracle全面得多。
??? Oracle沒有實現一般數據庫理論里的鎖機制,帶來的并發性與性能上的提升以及相關的問題上文已經介紹了,
現在來說說幾乎完全實現一般數據庫理論鎖機制的DB2數據庫這方面的實現。
??? 下面的資料來源于IBM資料庫DB2和 Oracle的并發控制(鎖)比較
??? 首先是鎖是屬性,有如下幾個基本屬性:鎖定對象,鎖定大小,鎖定時間,鎖定狀態。
鎖定對象表示鎖定的數據資源,DB2支持對表空間,表,行,索引(大型機里支持對數據頁)的鎖定。通常考慮表鎖與行鎖。
鎖定大小表示鎖定的數據大小。
鎖定時間通常由事務的隔離級別控制。
鎖定狀態就是鎖的類型,下面將會介紹。
表 1:DB2支持的表級鎖定
名稱縮寫???? 全名??????????????????????????????????? 描述
IN?????????? 無意圖鎖(Intent Node),不需要行鎖???? 擁有者可以讀取包括其他事務未提交數據在內的所有數據,但不能對表中的數據作出修改
IS?????? 意圖共享鎖(Intent Share),需要行鎖配合??? 擁有者可以在擁有相應行上的S鎖時可以讀取該行的數據,但不能修改數據
IX?? 意圖排他鎖(Intent eXclusive),需要行鎖配合??? 擁有者可以在擁有相應行上的X鎖時可以修改該行的數據
SIX 共享并且意圖排他鎖(Share with Intent eXclusive),需要行鎖配合?? 擁有者可以讀取表中的任何數據,如果在相應的行上可以獲得X鎖,可以修改該行。SIX的獲取比較特殊,當程序擁有IX鎖時請求S鎖,或者在已經擁有S鎖的時候請求IX鎖時產生
S???????????????? 共享鎖(Share),不需要行鎖配合??? 可以讀取表上的任何數據,如果表上被加了S鎖,表上的數據只能被讀取而不能做出任何修改
U??????????????? 更新鎖(Update),不需要行鎖配合??? 擁有者可以讀取表中的任何數據,如果升級為X鎖,則可以更改表中的任何數據,該鎖是等待對數據進行修改的一種中間狀態
X???????????? 排他鎖(eXclusive),不需要行鎖配合??? 擁有者可以讀取或者修改表中的任意數據,如果加上了X鎖,除了未提交讀事務外,其他程序都不能對表進行任何讀取或者修改
Z?? 超級排他鎖(Super eXclusive),不需要行鎖配合??? 該鎖一般不是由DML產生,而是由Drop,Alter或者創建刪除索引時產生的,加上Z鎖后,所有程序(包括未提交讀程序)都不能對表進行讀取或者修改
具體來說,IS,IX,SIX用于表一級并且需要行鎖配合,用于阻止其他程序對表加上排他鎖。區別如下:
·? 如果一個程序獲得表的IS鎖,程序可以獲得某一行上的S鎖用于只讀操作,其他程序也可以讀取該行,或者對表中其他行作出修改。
·? 如果一個程序獲得表的IX鎖,程序可以獲得某一行的X鎖用于更改操作,其他程序可以更改或者讀取表中其他的行。
·? 如果一個程序獲得表的SIX鎖,程序可以獲得某一行的X鎖用于更改操作,其他程序只能對表中的其他行進行只讀操作。
S,U,X,Z用于表一級,不需要行鎖的配合。區別如下:
·? 如果程序得到表的S鎖,則程序可以讀表中的任意數據,同時允許其他程序獲得表上的只讀鎖請求,如果有程序需要更改表上的數據,必須等到S鎖釋放。
·? 如果程序得到U鎖,程序可以讀取表中任意數據,最終可以通過獲得X鎖得到對表中任意數據的修改權,其他程序只能讀取表中的數據,U鎖與S鎖的區別在于修改意圖,U鎖的設計主要是為了避免兩個程序在擁有S鎖的情況下同時申請X鎖導致死鎖。
·? 如果程序得到表上的X鎖,程序可以讀或者修改表上任意數據,其他程序無法讀或者修改表上的數據。
·? 如果程序獲得Z鎖,程序可以讀或者修改表中任意數據,其他程序包括未提交讀程序在內不能對表執行讀或者修改操作。
IN鎖用于表上以允許未提交讀這一概念。
DB2支持的行鎖如下所示:
名稱縮寫????? 全名?????????????? 需要表鎖最低級別???????????????? 描述
S?????????? 共享鎖(Share)???????? IS??????????????????????????? 該行正在被讀取,其他程序只能執行讀操作
U?????????? 更改鎖(Update)??????? IX??????????????????????????? 某個程序正在讀取并有可能修改該行,其他程序只能讀取該行
X?????????? 排他鎖(eXclusive)???? IX??????????????????????????? 該行正在被某個程序修改,其他程序不能訪問該行
W??? 弱排他鎖(Weak eXclusive)???? IX??????????????????????????? 一行被插入表后,該行會加上W鎖,只有鎖的擁有者可以修改該行,與X鎖的不同在于該鎖與NW鎖兼容
NS?? 下一鍵共享鎖(Next Share)???? IS??????????????????????????? 擁有者與其他程序都可以讀取該行,但不能進行修改,當程序處于RS或者CS隔離級別下時,該鎖可以代替S鎖
NX? 下一鍵排他鎖(Next? eXclusive) IX??????????????????????????? 一行的數據被插入到索引或者從索引被刪除時,該行的下一行會被加上NX鎖,鎖的擁有者可以讀該行的數據但不能修改。該鎖與X鎖類似,但與NS鎖兼容
NW? 下一鍵弱排他鎖(Next? Weak eXclusive) IX???????????????????? 一行的數據被插入到索引時,該行的下一行會被加上NW鎖,鎖的擁有者可以讀但不能修改該行的數據,與X鎖及NX鎖類似,但與W鎖以及NS鎖兼容
默認情況下,DB2總是嘗試獲取行鎖,但可以使用ALTER TABLE語句修改為總是獲取表鎖,也可以使用LOCK TABLE語句獲取表鎖。
??? 以上就是DB2復雜的鎖機制,相比較Oracle,DB2沒有做任何樂觀假設,寫必須阻塞讀,讀必須阻塞寫,不然會影響讀一致性,這是最正統的數據庫理論。
不過對于開發人員來說,這種鎖機制就是一個噩夢,在寫任何并發性程序之前,首先就是要分析鎖,我前后用了兩天才理順DB2里各種鎖之間的關系,話說,
如果可以理解上面兩張鎖阻塞表,估計就可以對DB2鎖機制有一個清醒的認識了。
??? 下面是DB2的事務隔離級別,話說我一直以為只有事務級與語句級隔離級別,直到我看了DB2的事務隔離級別。
??? 首先是可重復讀(RR-RepeatableRead)級別,這一級別怎么說呢,概括一點,這個級別會鎖定所有使用到的表,直到事務結束,
保證事務開始一直到結束所可能需求的數據沒有任何變化。即事務運行時,其他程序無法修改其所用到的表,
這一級別類似oracle的事務級隔離級別,但Oracle沒有鎖定表,只是假定沒有人去修改所需求的數據。
??? 下一個是讀穩定性(RS-ReadStability)級別,這一級別只鎖定真正使用到的行(包括修改的行以及檢索到的行),而且可以讀到其他已提交事務的數據。
??? 在往下是游標穩定性(CS-CursorStability)級別,這一級別類似Oracle的語句級隔離級別,鎖定的只有修改了的行,可以讀取已提交事務的數據。
??? 最后是未提交讀(UR-UncommittedRead)級 別,這一級別如題,可以讀到未提交的數據,不過如果修改了數據,則其表現與CS相同,即鎖定修改了的行防止別的會話修改。
??? 四個事務級別,確保所有可能需要的數據不要被人修改->確保已經讀取的數據不要被人修改->確保修改的數據不要被別人修改->可以讀取別人未提交的數據(修改的數據同樣不允許被別的程序修改)。
下一個討論的是鎖轉換。
??? 當程序向數據庫請求它已經加鎖的對象上面的鎖的時候,數據庫會比較對象上現在的鎖與所請求的鎖的模式,如果所請求的鎖級別更高,則把現在的鎖升級為請求的鎖。
??? 鎖級別比較:
??? 表鎖:IN<IS<S<IX<U<X<Z
??? 行鎖:S<U<X
??? 有一個特殊例子是,如果持有S鎖請求IX鎖,或者持有IX鎖請求S鎖,鎖轉換結果為SIX鎖。
??? 下面來談談DB2里著名的鎖升級問題。
??? 在學Oracle的時候,我從來不知道鎖升級這個概念,這是由于Oracle中,鎖并不是稀缺資源,沒必要把多個鎖合并為同一個鎖來減少資源占用。
??? DB2里有兩個參數,LOCKLIST與MAXLOCKS,LOCKLIST表示數據庫分配的用來儲存鎖列表的空間大小,MAXLOCKS表示程序最大允許占用鎖列表大小的百分比,
當超過這個百分比的時候,就會進行鎖升級,這里我就不發那長長的一大串DB2鎖列表計算公式了,只需要知道,DB2會在一個程序鎖定過多行的時候,
會把鎖定多行變更為鎖定整個表。這是一個Oracle里沒有的概念,如果從Oracle轉為DB2,需要注意。
??? 最后說說鎖等待,這里類似Oracle里的nowait選項,DB2里面有一個參數LOCKTIMEOUT,可以設置這個參數的值來設定遇到鎖阻塞后的等待時間,如果超時的話就會回滾語句。
??? 在DB2的開發建議里,為了實現并行化與數據完整性,有如下幾個建議,比較Oracle的類似建議的話,相當有意思。
·? 頻繁使用commit來使多個用戶可以并發地訪問數據(Oracle中的建議是盡可能維護業務事務的完整性,而不是切割成小事務)
·? 發出commit語句前,關閉CURSORWITH HOLD來確保所有鎖都得到釋放(Oracle中事務提交或者回滾后自動解鎖,不需要其他操作)
·? 指定適當的隔離級別。DB2會借助一切機會鎖定行,需要不同的隔離級別來協調(Oracle在必要的時候使用事務級隔離,一般只需要語句級隔離級別)
·? 適當使用LOCKTABLE語句(盡可能不要使用也很少有必要使用LOCL TABLE語句)
DB2的開發建議還有很多,感興趣的可以去看看相關資料,與Oracle的開發建議比較相當有意思的。
關于兩個數據庫鎖與并行的介紹就到這里,這篇文章中沒有介紹DB2并發性的問題,但其實也沒必要介紹,在鎖機制部分已經到達并發性的瓶頸,并發性在DB2的鎖機制下受到的限制太大了。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
