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