在DB2數據庫中, 是通過行級鎖和表級鎖協調作用來提供較好的並發性, 同時保證數據庫中數據的安全。 在DB2中缺省情況下使用行級鎖(當然需要IS/IX鎖配合),只有當出現鎖資源不足, 或者是用命令指定使用表級鎖的情況下, 才會在應用連接中使用表級鎖。 對鎖資源分配有興趣的讀者可以參考DB2的管理手冊, 查找其中關於locklist和maxlocks參數的論述。對於用命令指定表級鎖的情況, 可以參考DB2的命令手冊中的lock table命令, 此命令用於直接鎖表。
隔離級別主要用於控制在DB2根據應用提交的SQL語句向DB2數據庫中的相應對象加鎖時, 會鎖住哪些紀錄, 也就是鎖定的范圍。 隔離級別的不同, 鎖定的紀錄的范圍可能會有很大的差別。
隔離級別分為RR/RS/CS/UR這四個級別。 下面讓我們來逐一論述:
1. RR隔離級別: 在此隔離級別下, DB2會鎖住所有相關的紀錄。 在一個SQL語句執行期間, 所有執行此語句掃描過的紀錄都會被加上相應的鎖。 具體的鎖的類型還是由操作的類型來決定, 如果是讀取,則加共享鎖; 如果是更新, 則加獨占鎖。 由於會鎖定所有為獲得SQL語句的結果而掃描的紀錄, 所以鎖的數量可能會很龐大, 這個時候, 索引的增加可能會對SQL語句的執行有很大的影響,因為索引會影響SQL語句掃描的紀錄數量。
2. RS隔離級別: 此隔離級別的要求比RR隔離級別稍弱,此隔離級別下會鎖定所有符合條件的紀錄。 不論是讀取, 還是更新, 如果SQL語句中包含查詢條件, 則會對所有符合條件的紀錄加相應的鎖。 如果沒有條件語句, 也就是對表中的所有記錄進行處理,則會對所有的紀錄加鎖。
3. CS隔離級別: 此隔離級別僅鎖住當前處理的紀錄。
4. UR隔離級別:此隔離級別下,如果是讀取操作,不會出現任何的行級鎖。對於非只讀的操作,它的鎖處理和CS相同。
在這四種隔離級別中, CS是缺省值。 這四種隔離級別均可以保證DB2數據庫在並發的環境下不會有數據丟失的情況發生。 要注意的是如果對紀錄進行了修改,需要在相應的紀錄上加獨占類型的鎖, 這些獨占類型的鎖直到交易結束時才會被釋放, 這一點在四種隔離級別下都是相同的。
到這里, 我們已經對DB2中的表鎖, 行鎖, 隔離級別進行了論述。 DB2數據庫的並發控制主要是通過這些機制。 理解了這些概念,我們就可以在使用DB2數據庫時根據系統的實際需要來設計鎖模式和隔離級別, 來實現我們的系統要求, 在保障數據安全的前提下, 提供較好的並發性。
如果還需要了解更多的相關DB2數據庫的並發控制, 鎖, 和隔離級別的相關信息, 可以參考以下的文檔說明:
1. DB2 Command Reference
2. DB2 Administrator Reference
我們在這里將簡要的闡述一下鎖和隔離級別。
鎖:
DB2 UDB中, 鎖的主要作用對象是表和行, 其他如表空間和索引也是鎖的對象, 但是因為其多為系統控制, 管理員和用戶使用較少,在這里就不涉及了。
對於行級鎖和表級鎖, 它們的區別不言而喻, 主要是鎖的對象不同。 當然鎖對象的不同連帶也會影響DB2的並發能力。
DB2中的表級鎖主要有以下幾種:
1. IS鎖: 此鎖作用於整個表,表示擁有此鎖的應用連接要讀取表中的某些數據, 但是在此應用連接讀取具體的數據時, 還必須獲得該行的行級鎖;
2. IX鎖: 此鎖作用於整個表,表示擁有此鎖的應用連接需要獨占使用表中的某些數據, 但是在此應用連接獨占使用具體的數據時, 還必須獲得該行上相應的行級鎖;
3. SIX鎖: 此鎖是鎖轉換的產物,表示應用連接擁有S和IX鎖的特性;
4. S鎖: 此鎖作用於整個表, 擁有此鎖的應用連接可以讀取表中的任何紀錄;
5. U鎖: 此鎖作用於整個表, 擁有此鎖的應用連接可以讀取表中的任何紀錄,也可以更新表中的紀錄, 但是更新時需要再獲得X鎖; 此鎖主要在“select … with update”語句建立的可更新游標中起作用, 其他的應用可以讀取表中的紀錄, 但是不能更新它;
6. X鎖: 此鎖作用於整個表, 擁有此鎖的應用連接獨占的使用表中的任何紀錄;可以進行更新或其他操作;
7. Z鎖: 此鎖作用於整個表, 也稱超級獨占鎖,主要是在象修改表的定義、 刪除表這一類的語句中會使用。 擁有此鎖的應用連接對該表有完全的控制權。 其他的任何應用不能讀取或更新表中的任何紀錄。
在這里我們主要要看一下 IS/IX/SIX這三個鎖。 在這三個鎖中IS/IX本身並不具備使得應用連接可以讀取或更新紀錄的能力,應用連接要讀取和更新紀錄時, 需要再得到相應的行級鎖; 反之亦然, 任何應用要獲得行級鎖操作數據記錄之前, 也必須獲得某個相應的表級鎖。 SIX鎖也是類似的情況。這就是為什麽在很多情況下我們使用的是行級鎖, 但是用快照(SNAPSHOT)等工具卻能夠看到有表級鎖存在的原因。
那麽DB2中又有哪些行級鎖呢? 讓我們來看下面的這張圖:
此圖中列出了DB2中包含的行級鎖。 表中的第三列指出, 要獲得此行級鎖之前, 需要預先獲得的表級鎖, 這里列出的是最低要求。
這六個行級鎖的主要功能如下:
1. S鎖:此行級鎖的擁有者可以讀取該行的信息;
2. U鎖:此行級鎖的擁有者可以讀取該行的信息,如果要更新該行,則仍然需要一個行級的X鎖;其他的應用只能讀取該行的信息;此鎖主要是用於FOR UPDATE的游標。
3. X鎖:此行級鎖的擁有者可以更新該行的紀錄,其他的應用不能連接此行的信息;
4. W鎖:此鎖和X鎖類似,不同之處是此鎖和NW鎖兼容;
6. NW鎖:類似於W鎖,用於Next Key;
在DB2數據庫中, 是通過行級鎖和表級鎖協調作用來提供較好的並發性, 同時保證數據庫中數據的安全。 在DB2中缺省情況下使用行級鎖(當然需要IS/IX鎖配合),只有當出現鎖資源不足, 或者是用命令指定使用表級鎖的情況下, 才會在應用連接中使用表級鎖。 對鎖資源分配有興趣的讀者可以參考DB2的管理手冊, 查找其中關於locklist和maxlocks參數的論述。對於用命令指定表級鎖的情況, 可以參考DB2的命令手冊中的lock table命令, 此命令用於直接鎖表。
隔離級別
在DB2中,共有四種隔離級:RS,RR,CS,UR.以下對四種隔離級進行一些描述,同時附上個人做試驗的結果。隔離級是影響加鎖策略的重要環節,它直接影響加鎖的范圍及鎖的持續時間。
基本信息
在DB2中,共有四種隔離 級:RS,RR,CS,UR.以下對四種隔離級進行一些描述,同時附上個人做試驗的結果。隔離級是影響加鎖策略的重要環節,它直接影響加鎖的范圍及鎖的持 續時間。兩個應用程序即使執行的相同的操作,也可能由於選擇的隔離級的不同而造成加鎖的結果不同。
隔離級解讀和試驗
隔離級是影響加鎖策略的重要環節,它直接影響 加鎖的范圍及鎖的持續時間。兩個應用程序即使執行的相同的操作,也可能由於選擇的隔離級的不同而造成加鎖的結果不同。在DB2中,共有四種隔離 級:RS,RR,CS,UR.以下對四種隔離級進行一些描述,同時附上個人做試驗的結果。
- 讀可靠性(RS-Read Stability)
如果使用這種隔離級,在一個事務中所有被讀取過的行上都會被加上NS鎖,直到該事務被提交或回滾,行上的鎖才會被釋放。這樣可以保證在一個事務中即使多次讀取同一行,得到的值不會改變。
但是,如果使用這種隔離級,在一個事務中,如果使用同樣的搜索標准重新打開已被處理過的游標,則結果集可能改變。(可能會增加某些行,這些行被稱為幻影行(Phantom))。這是因為RS隔離級不能阻止通過插入或更新操作在結果集中加入新行。
個人筆記:
根據實際測試情況,RS模式下:查詢完畢以后,滿足條件的結果集中的記錄被鎖定,不滿足條件的不被鎖定。
可以對不滿足條件的記錄更新,也可以插入新的記錄。其他人可以查詢滿足已經鎖定的記錄,但不可以更新。
- 重復讀(RR-Repeat Read)
如果使用這種隔離級,在一個事務中所有被讀取過的行上都會被加上S鎖,知道該事務被提交或回滾,行上的鎖才會被釋放。這樣可以保證在一個事務中即使多次讀取同一行,得到的值不會改變。
另外,在同一事務中如果以同樣的搜索標准重新打開已被處理過的游標,得到的結果集不會改變。重復讀相對於讀可靠性而言,加鎖的范圍更大。
對於讀可靠性,應用程序只對符合要求的所有行加鎖,而對於重復讀,應用程序將對所有被掃描過的行都加鎖。例如,如果一個應用程序對一個表中的 10000行數據進行掃描,最終找到了100條符合搜索條件的結果行。如果該應用程序使用的是讀可靠性隔離級,應用程序將只對這符合條件的100行加鎖;如果該應用程序使用的是重復讀隔離級,應用程序將對被掃描過的10000行都加鎖。
個人筆記
根據實際測試情況,RR模式下:查詢完畢以后,不可以對不滿足條件的進行更新,也不可以插入新記錄。可能原因是:如果允許別人更新記錄或者插入新記錄的話,則可能造成原來結果集的破壞,重新讀的時候和以前不同。
select for update with rr/rs 是可以用來實現記錄鎖。是一種特殊情況。即便是RR,仍然可以對其他記錄操作。
- 游標可靠性(CS-Cursor Stability)
如果使用這種隔離級,在一個事務中,結果集中只有正在被讀取的那一行(游標指向的行)將被加上NS鎖,其他未被處理的行上不被加鎖。這種隔離級只能保證正在被處理的行的值不會被其他並發的程序所改變。該隔離級是DB2缺省的隔離級。
個人筆記
僅僅在游標在該行的時候鎖定,這是一種非常弱的隔離狀態。
- 未提交讀(UR-Uncommitted Read)
如果使用這種隔離級,對於只讀操作,不加行鎖。典型的只讀操作包括:
SELECT語句的結果集只讀(比如語句中包括ORDER BY子句);
定義游標是指明起為FOR FETCH ONLY。
該隔離級可以改善應用程序的性能,同時可以最大程度的允許並發。但是,應用程序的數據完整性將受到威脅。如果需要讀取未提交的數據,該隔離級是唯一選擇。
個人筆記
讀的時候完全不受限制,對於同一行記錄的完整性也無法保證。
總結
以上我們所提的隔離級的加鎖范圍和持續時間都是針對於讀操作而言的。