以下的文章主要向大家講述的是B2隔離級別與性能,隔離級別主要是確定訪問數據時如何鎖定數據或是使數據不受其他進程影響。該隔離級別是在工作單元運行期間生效。在執行 OPEN CURSOR 的工作單元期間。
使用由 WITH HOLD 子句的 DECLARE CURSOR 語句聲明的游標的應用程序將保持選定的DB2隔離級別。DB2® 支持下列隔離級別:
可重復讀
讀穩定性
游標穩定性
未落實的讀。
注: 某些主機數據庫服務器支持不落實隔離級別。對於其他數據庫,此隔離級別的行為與未落實的讀隔離級別一樣。
每個隔離級別的詳細說明按它們對性能的影響程度的降序排列,但按您訪問和更新數據時需要加以關心的程度的升序排列。
可重復讀
可重復讀(RR)會鎖定應用程序在工作單元中引用的所有行。利用“可重復讀”,在打開游標的相同工作單元內一個應用程序發出一個 SELECT 語句兩次,每次都返回相同的結果。利用“可重復讀”,不可能出現丟失更新、訪問未落實的數據和幻像行的情況。
在該工作單元完成之前,“可重復讀”應用程序可以盡可能多次地檢索和操作這些行。但是,在該工作單元完成之前其他應用程序均不能更新、刪除或插入可能會影響結果表的行。“可重復讀”應用程序不能查看其他應用程序的未落實更改。
利用“可重復讀”,將會鎖定引用的每一行,而不僅僅是檢索的那些行。執行了適當的鎖定,因此其他應用程序不能插入或更新行(該行可能要添加到查詢所引用的行的列表中,如果重新執行查詢)。這將防止出現幻像行。例如,如果您掃描 10000 行並對它們應用謂詞,盡管只有 10 行滿足條件,但仍會鎖定全部的 10000 行。
注: “可重復讀”隔離級別確保在應用程序看到數據之前所有返回的數據都保持不變,即使使用了臨時表或行分塊也是如此。
由於“可重復讀”可能獲得和掛起大量鎖定,因此這些鎖定可能超出可作為 locklist 和 maxlocks 配置參數的有效結果的鎖定數。為了避免鎖定升級,優化器在認為很可能會發生鎖定升級的時候,可能選擇立即獲得單個表級別鎖定用於索引掃描。這就像數據庫管理器代表您發出了一個 LOCK TABLE 語句一樣。如果不想獲得表級別鎖定,確保有足夠的鎖定可用於該事務或使用“讀穩定性”隔離級別。
評估引用約束時,在一些情況下,DB2 將在內部把對外部表進行掃描所使用的DB2隔離級別升級到“可重復讀”(RR),而無論用戶設置的隔離級別是什麼。這將導致其他鎖定在落實之前一直被掛起,從而增大了出現死鎖或鎖定超時的可能性。為了避免出現這種情況,建議您創建僅包含一列或多列外鍵的索引,從而允許 RI 掃描使用此索引。
讀穩定性
讀穩定性(RS)只鎖定應用程序在工作單元中檢索的那些行。它確保在某個工作單元完成之前,在該工作單元運行期間的任何限定行讀取不被其他應用程序進程更改,且確保不會讀取由另一個應用程序進程所更改的任何行,直至該進程落實了這些更改。也就是說,不可能出現“不可重復讀”情形。
與可重復讀不同,使用“讀穩定性”時,如果您的應用程序多次發出相同的查詢,那麼有可能看到附加的幻像行(幻像讀現象)。重新引用掃描 10000 行的示例時,“讀穩定性”只鎖定限定的行。這樣,使用“讀穩定性”時,只檢索 10 行,且只對那十行掛起鎖定。將它與“可重復讀”對比,在本示例中,可重復讀會在所有的 10000 行上掛起鎖定。掛起的鎖定可以是共享、下次共享、更新或互斥鎖定。
注: “讀穩定性”隔離級別確保在應用程序看到數據之前所有返回的數據保持不變,即使使用了臨時表或行分塊也是如此。
“讀穩定性”隔離級別的其中一個目標是提供較高並行性程度以及數據的穩定視圖。為了有助於達到此目標,優化器確保在發生鎖定升級前不獲取表級鎖定。
“讀穩定性”隔離級別最適用於包括下列所有特征的應用程序:
在並發環境下運行
需要限定某些行在工作單元運行期間保持穩定
在工作單元中不會多次發出相同的查詢,或者在同一工作單元中發出多次查詢時並不要求該查詢獲得相同的回答。
游標穩定性
游標穩定性(CS)當在行上定位游標時會鎖定任何由應用程序的事務所訪問的行。此鎖定在讀取下一行或終止事務之前有效。但是,如果更改了某一行上的任何數據,那麼在對數據庫落實更改之前必須掛起該鎖定。
對於具有“游標穩定性”的應用程序已檢索的行,當該行上有任何可更新的游標時,任何其他應用程序都不能更新或刪除該行。“游標穩定性”應用程序不能查看其他應用程序的未落實更改。
再次引用掃描 10000 行的示例,如果使用“游標穩定性”,將只鎖定當前游標位置以下的行。當游標移離該行時,也就除去了該鎖定(除非更新該行)。
使用“游標穩定性”,可能會出現不可重復讀和幻像讀現象。“游標穩定性”是缺省隔離級別,且應在需要最大並行性,但只看到其他應用程序中的已落實行的情況下才使用。
未落實的讀
未落實的讀(UR)允許應用程序訪問其他事務的未落實的更改。除非其他應用程序嘗試刪除或改變該表,否則該應用程序也不會鎖定正讀取的行而使其他應用程序不能訪問該行。對於只讀和可更新的游標,“未落實的讀”的工作方式有所不同。
只讀游標可訪問大多數其他事務的未落實的更改。但是,當該事務正在處理時,正由其他事務創建或刪除的表、視圖和索引不能使用。其他事務的任何其他更改在落實或回滾前都可被讀取。
注: “未落實的讀”隔離級別下的可更新操作的游標將按隔離級別是游標穩定性的方式工作。
當它使用隔離級別 UR 運行程序時,應用程序可以使用隔離級別 CS。發生這種情況的原因是因為在應用程序中使用的游標是模糊游標。由於 BLOCKING 選項,可以將模糊游標升級為隔離級別 CS。BLOCKING 選項的缺省值是 UNAMBIG。這意味著將模糊游標當作可更新的,並且DB2隔離級別升級為 CS。要防止此升級,有兩種選擇:
修改應用程序中的游標。以便這些游標是非模糊游標。將 SELECT 語句更改為包括 FOR READ ONLY 子句。
將模糊游標保留在應用程序中,但是預編譯程序或使用 BLOCKING ALL 和 STATICREADONLY YES 選項綁定它以允許在運行該程序時將任何模糊游標視為只讀游標。
如對掃描 10000 行的“可重復讀”給出的示例一樣,如果使用“未落實的讀”,那麼不需要任何行鎖定。
使用“未落實的讀”,可能出現不可重復讀行為和幻像讀現象。“未落實的讀”隔離級別最常用於只讀表上的查詢,或者若僅執行選擇語句且不關心是否可從其他應用程序中看到未落實的數據時也最常用。
隔離級別的摘要
下表按不期望的結果概述了幾個不同的隔離級別。
表 1. 隔離級別摘要
隔離級別 訪問未落實的數據 不可重復讀 幻像讀現象
可重復讀(RR) 不可能 不可能 不可能
穩定性(RS) 不可能 不可能 可能
游標穩定性(CS) 不可能 可能 可能
未落實的讀(UR) 可能 可能 可能
下表提供了簡單的試探方法,以幫助您為應用程序選擇初始隔離級別。首先考慮下表列示的方法,並參閱先前對各級因素的討論,可能會找到另一個更適合的隔離級別。
表 2. 選擇隔離級別的准則
應用程序類型 需要高數據穩定性 不需要高數據穩定性
讀寫事務 RS CS
只讀事務 RR 或 RS UR
為一個應用程序選擇適當的隔離級別對於該應用程序避免無法容忍的現象很重要。因為獲取和釋放鎖定所需的 CPU 和內存資源隨隔離級別的不同而不同,所以此隔離級別不但影響應用程序之間的隔離程度,而且還影響個別應用程序的性能特征。潛在的死鎖情況隨DB2隔離級別的不同而不同。