青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

隔離級別和鎖

Posted on 2010-03-17 09:46 Prayer 閱讀(756) 評論(0)  編輯 收藏 引用 所屬分類: 數據庫,SQLDB2

我們在進行客戶支持時遇到最多的話題之一就是鎖。“為什么 DB2 鎖住了這個表、行或者對象?”,“這個鎖會阻塞多長時間及為什么?”;“為什么出現(xiàn)了死鎖?”,“我的鎖請求在等待什么?”,諸如此類問題等等。更仔細地分析一些常見的鎖示例可以說明DB2鎖定策略背后的原則。在國內很多DB2用戶都會碰到有關鎖等待、死鎖和鎖升級等鎖相關的問題,本章將會對這些問題以及解決方法做詳細的講解。

本章主要講解如下內容:

●       隔離級別和鎖

●       加鎖總結

●       樂觀鎖

●       內部鎖

●       設置鎖相關的注冊變量

6.1  隔離級別和鎖

要維護數據庫的一致性和數據完整性,同時又允許多個應用程序同時訪問一個數據庫,將這樣的特性稱為并發(fā)性。DB2數據庫嘗試強制實施并發(fā)性的方法之一是使用隔離級別,它決定在第一個事務訪問數據時,如何對其他事務鎖定或隔離該事務所使用的數據。DB2使用下列隔離級別來強制實施并發(fā)性:

●       可重復讀(Reapeatable Read,RR)

●       讀穩(wěn)定性(Read Stability,RS)

●       游標穩(wěn)定性(Cursor Stability,CS)

●       未提交的讀(Uncommitted Read,UR)

隔離級別是根據稱為現(xiàn)象(Phenomena)的三個禁止操作序列來聲明的:

●       臟讀(Dirty Read):在事務A提交修改結果之前,其他事務即可看到事務A的修改結果。

●       不可重復讀(Non-Repeatable Read):在事務A提交之前,允許其他事務修改和刪除事務A涉及的數據,導致事務A中執(zhí)行同樣操作的結果集變小。

●       幻像讀(Phantom Read):事務A在提交查詢結果之前,其他事務可以插入或者更改事務A涉及的數據,導致事務A中執(zhí)行同樣操作的結果集增大。

數據庫并發(fā)性(可以同時訪問同一資源的事務數量)因隔離級別不同而有所差異,可重復讀隔離級別可以防止所有現(xiàn)象,但是會大大降低并發(fā)性。未提交讀隔離級別提供了最大的并發(fā)性,但可能會造成“臟讀”、“幻像讀”或“不可重復讀”現(xiàn)象。DB2默認的隔離級別是CS。

6.1.1  可重復讀

可重復讀隔離級別是最嚴格的隔離級別。在使用它時,一個事務的操作結果完全與其他并發(fā)事務隔離,臟讀、不可重復讀、幻像讀都不會發(fā)生。當使用可重復讀隔離級別時,在事務執(zhí)行期間會共享(S)鎖定該事務以任何方式引用的所有行,在該事務中多次執(zhí)行同一條SELECT語句,得到的結果數據集總是相同的。因此,使用可重復讀隔離級別的事務可以多次檢索同一行集,并可以對它們執(zhí)行任意操作,直到提交或回滾操作終止事務。但是,在事務提交前,不允許其他事務執(zhí)行會影響該事務正在訪問的任何行的插入、更新或刪除操作。為了確保這種行為,需要鎖定該事務所引用的每一行—— 而不是僅鎖定被實際檢索或修改的那些行。因此,如果一個表中有1000行,但只檢索兩行,則整個表(1000行,而不僅是被檢索的兩行)都會被鎖定。輸出結果如下:

C:\>db2 +c select empno,firstnme,salary from employee where empno between '000010' and '000020' with  rr

EMPNO  FIRSTNME     SALARY

------ ------------ -----------

000010 CHRISTINE      152750.00

000020 MICHAEL         94250.00

  2 條記錄已選擇。

我們通過“get snapshot for locks on sample”命令來監(jiān)控表加鎖情況,輸出結果如下:

C:\>db2 update monitor switches using lock on

DB20000I  UPDATE MONITOR SWITCHES命令成功完成。

C:\>db2 get snapshot for locks on sample | more

--------------略------------------

鎖定列表

鎖定名稱                       = 0x020006000E0040010000000052

鎖定屬性                       = 0x00000010

發(fā)行版標志                     = 0x00000004

鎖定計數                       = 1

掛起計數                       = 0

鎖定對象名                     = 20971534

對象類型                       = 表

表空間名                       = USERSPACE1

表模式                        = DB2ADMIN

表名                         = EMPLOYEE

方式                           = S    --注:雖然讀取了兩行,但是整個表加S鎖

如果使用這種隔離級別,不管你從表中讀多少數據,整個表上都加S鎖,直到該事務被提交或回滾,表上的鎖才會被釋放。這樣可以保證在一個事務中即使多次讀取同一行,都會得到相同結果集。另外,在同一事務中如果以同樣的搜索標準重新打開已被處理過的游標,那么得到的結果集不會改變。可重復讀相對于讀穩(wěn)定性而言,加鎖的范圍更大:對于讀穩(wěn)定性,應用程序只對符合要求的所有行加鎖;而對于重復讀,應用程序將對整個表都加S鎖。

可重復讀會鎖定應用程序在工作單元中引用的整個表。利用可重復讀,一個應用程序在打開游標的相同工作單元內發(fā)出一個SELECT語句兩次,每次都返回相同的結果。利用可重復讀隔離級別,不可能出現(xiàn)丟失更新、臟讀和幻像讀的情況。

在該工作單元完成之前,“可重復讀”應用程序可以多次檢索和操作這些行。但是,在該工作單元完成之前其他應用程序均不能更新、刪除或插入可能會影響結果表的行。“可重復讀”應用程序不能查看其他應用程序未提交的更改。

6.1.2  讀穩(wěn)定性

讀穩(wěn)定性隔離級別沒有可重復讀隔離級別那么嚴格;因此,它沒有將事務與其他并發(fā)事務的效果完全隔離。讀穩(wěn)定性隔離級別可以防止臟讀和不可重復讀,但是可能出現(xiàn)幻像讀。在使用這個隔離級別時,只鎖定事務實際檢索和修改的行。因此,如果一個表中有1000行,但只檢索兩行(通過索引掃描),則只鎖定被檢索的兩行(而不是所掃描的 1000 行)。因此,如果在同一個事務中發(fā)出同一個SELECT語句兩次或更多次,那么每次產生的結果數據集可能不同。

與可重復讀隔離級別一樣,在讀穩(wěn)定性隔離級別下運行的事務可以檢索一個行集(ROWS SET),并可以對它們執(zhí)行任意操作,直到事務終止。在這個事務存在期間,其他事務不能執(zhí)行那些會影響這個事務檢索到的行集的更新或刪除操作,但是可以執(zhí)行插入操作。如果插入的行與第一個事務的查詢的選擇條件匹配,那么這些行可能作為幻像出現(xiàn)在后續(xù)產生的結果數據集中。其他事務對其他行所作的更改,在提交之前是不可見的。下面我們還用上面的那個例子鎖定讀穩(wěn)定性,輸出結果如下:

C:\>db2 +c select empno,firstnme,salary from employee where empno between '000010' and '000020' with  rs

EMPNO  FIRSTNME     SALARY

------ ------------ -----------

000010 CHRISTINE      152750.00

000020 MICHAEL         94250.00

  2 條記錄已選擇。

我們通過“get snapshot for locks on sample”命令來監(jiān)控表加鎖情況,輸出結果如下:

C:\>db2 update monitor switches using lock on

DB20000I  UPDATE MONITOR SWITCHES命令成功完成。

C:\>db2 get snapshot for locks on sample | more

--------------略------------------

鎖定列表

鎖定名稱                       = 0x02000600050040010000000052

鎖定屬性                       = 0x00000010

發(fā)行版標志                     = 0x00000001

鎖定計數                       = 1

掛起計數                       = 0

鎖定對象名                     = 20971525

對象類型                       = 行

表名                      = EMPLOYEE

方式                           = S --注:只在讀取的行上加S鎖

鎖定名稱                       = 0x02000600040040010000000052

鎖定屬性                       = 0x00000010

發(fā)行版標志                     = 0x00000001

鎖定計數                       = 1

掛起計數                       = 0

鎖定對象名                     = 20971524

對象類型                       = 行

表名                      = EMPLOYEE

方式                           = S --注:只在讀取的行上加S鎖

鎖定名稱                       = 0x02000600000000000000000053

鎖定屬性                       = 0x00000010

發(fā)行版標志                     = 0x00000001

鎖定計數                       = 1

掛起計數                       = 0

鎖定對象名                     = 6

對象類型                       = 表

表名                      = EMPLOYEE

方式                           = IS --注:表上加IS鎖

如果使用這種隔離級,那么在一個事務中將有N+1個鎖,其中N是所有被讀取(通過索引掃描)過的行的數目,這些行上都會被加上NS鎖,在表上加上1個IS鎖。這些鎖直到該事務被提交或回滾才會被釋放。這樣可以保證在一個事務中即使多次讀取同一行,得到的值也不會改變。但是使用這種隔離級別,在一個事務中,如果使用同樣的搜索標準重新打開已被處理過的游標,則結果集可能改變(可能會增加某些行,這些行被稱為幻影行(Phantom))。這是因為RS隔離級別不能阻止通過插入或更新操作在結果集中加入新行。

注意:

NS是下一鍵共享鎖,此時鎖擁有者和所有并發(fā)的事務都可以讀(但不能更改)被鎖定行中的數據。這種鎖用來在使用讀穩(wěn)定性或游標穩(wěn)定性事務隔離級別讀取的數據上代替共享鎖。

讀穩(wěn)定性(RS)只鎖定應用程序在工作單元中檢索的那些行。它確保在某個工作單元完成之前,在該工作單元運行期間的任何限定行讀取不被其他應用程序進程更改,且確保不會讀取由另一個應用程序進程所更改的任何行,直至該進程提交了這些更改。也就是說,不可能出現(xiàn)“不可重復讀”情形。

“讀穩(wěn)定性”隔離級別的其中一個目標是提供較高并行性以及數據的穩(wěn)定視圖,為了有助于達到此目標,優(yōu)化器確保在發(fā)生鎖定升級前不獲取表級鎖定。

“讀穩(wěn)定性”隔離級別最適用于包括下列所有特征的應用程序:

●       在并發(fā)環(huán)境下運行。

●       需要限定某些行在工作單元運行期間保持穩(wěn)定。

●       在工作單元中不會多次發(fā)出相同的查詢,或者在同一工作單元中發(fā)出多次查詢時并不要求該查詢獲得相同的回答。

6.1.3  游標穩(wěn)定性

游標穩(wěn)定性隔離級別在隔離事務效果方面非常寬松。它可以防止臟讀;但有可能出現(xiàn)不可重復讀和幻像讀。這是因為在大多數情況下,游標穩(wěn)定性隔離級別只鎖定事務聲明并打開的游標當前引用的行。

當使用游標穩(wěn)定性隔離級別的事務通過游標從表中檢索行時,其他事務不能更新或刪除游標所引用的行。但是,如果被鎖定的行本身不是用索引訪問的,那么其他事務可以將新的行添加到表中,以及對被游標鎖定行前后的行進行更新或刪除操作。所獲取的鎖一直有效,直到游標重定位或事務終止為止(如果游標重定位,原來行上的鎖就被釋放,并獲得游標現(xiàn)在引用的行上的鎖)。此外,如果事務修改了它檢索到的任何行,那么在事務終止之前,其他事務不能更新或刪除該行,即使在游標不再位于被修改的行時。與可重復讀和讀穩(wěn)定性隔離級別一樣,其他事務在其他行上進行的更改,在這些更改提交之前對于使用游標穩(wěn)定性隔離級別的事務(這是默認的隔離級別)是不可見的。我們還用上面那個例子,一個表中有1000行數據,我們只檢索其中兩行數據。那么對于可重復讀隔離級別會鎖住整個表,對于讀穩(wěn)定性隔離級別會對讀到的數據(兩行)加鎖,而對于游標穩(wěn)定性隔離級別只對游標當前所在那一行加鎖,游標所在行的前一行和下一行都不加鎖。下面我們舉一個游標穩(wěn)定性的例子,輸出結果如下:

C:\>db2 +c declare c1 cursor for  select empno,firstnme,salary from employee where empno between '000010' and '000020' with cs

C:\>db2 +c open c1

C:\>db2 +c fetch c1

EMPNO   FIRSTNME      SALARY

------ ------------ -----------

000010 CHRISTINE      152750.00   --注:游標當前所在行,DB2只對這一行加鎖。游標的

上一行和下一行都不加鎖。當游標移動到下一行時,鎖自動釋放。

  1 條記錄已選擇。

我們通過“get snapshot for locks on sample”命令來監(jiān)控表加鎖情況,輸出結果如下:

C:\>db2 update monitor switches using lock on

DB20000I  UPDATE MONITOR SWITCHES命令成功完成。

C:\>db2 get snapshot for locks on sample | more

--------------略------------------

鎖定名稱                         = 0x02000600040040010000000052

鎖定屬性                         = 0x00000010

發(fā)行版標志                       = 0x00000001

鎖定計數                         = 1

掛起計數                         = 0

鎖定對象名                       = 20971524

對象類型                       = 行

表名                          = EMPLOYEE

方式                             = S --注:只在游標所在行上加S鎖

鎖定名稱                         = 0x02000600000000000000000053

鎖定屬性                         = 0x00000010

發(fā)行版標志                       = 0x00000001

鎖定計數                         = 1

掛起計數                         = 0

鎖定對象名                       = 6

對象類型                       = 表

表名                            = EMPLOYEE

方式                            = IS --注:表上加IS鎖

如果使用這種隔離級,那么在一個事務中只有兩個鎖:結果集中只有正在被讀取的那一行(游標指向的行)被加上NS鎖,在表上加IS鎖。其他未被處理的行上不加鎖。這種隔離級別只能保證正在處理的行的值不會被其他并發(fā)的程序所改變。該隔離級別是DB2默認的隔離級別。

游標穩(wěn)定性(CS)當在行上定位游標時會鎖定任何由應用程序的事務所訪問的行。此鎖定在讀取下一行或終止事務之前有效。但是,如果更改了某一行上的任何數據,那么在對數據庫提交更改之前必須掛起該鎖定。

對于具有“游標穩(wěn)定性”的應用程序已檢索的行,當該行上有任何可更新的游標時,任何其他應用程序都不能更新或刪除該行。“游標穩(wěn)定性”應用程序不能查看其他應用程序的未提交操作。

使用“游標穩(wěn)定性”,可能會出現(xiàn)不可重復讀和幻像讀現(xiàn)象。“游標穩(wěn)定性”是默認隔離級別,應在需要最大并行性,但只看到其他應用程序中的已提交行的情況下才使用。

6.1.4  未提交讀

未提交讀隔離級別是最不嚴格的隔離級別。實際上,在使用這個隔離級別時,僅當另一個事務試圖刪除或更改被檢索的行所在的表時,才會鎖定一個事務檢索的行。因為在使用這種隔離級別時,行通常保持未鎖定狀態(tài),所以臟讀、不可重復讀和幻像讀都可能會發(fā)生。因此,未提交讀隔離級別通常用于那些訪問只讀表和視圖的事務,以及某些執(zhí)行SELECT語句的事務(只要其他事務的未提交數據對這些語句沒有負面效果)。

顧名思義,其他事務對行所做的更改在提交之前對于使用未提交讀隔離級別的事務是可見的。但是,此類事務不能看見或訪問其他事務DDL(CREATE、ALTER和DROP)語句所創(chuàng)建的表、視圖或索引,直到那些事務被提交為止。類似地,如果其他事務刪除了現(xiàn)有的表、視圖或索引,那么僅當進行刪除操作的事務終止時,使用未提交讀隔離級別的事務才能知道這些對象不再存在了。

一定要注意一點:當運行在未提交讀隔離級別下的事務使用可更新游標時,該事務的行為和在游標穩(wěn)定性隔離級別下運行一樣,并應用游標穩(wěn)定性隔離級別的約束。下面我們舉一個例子。

我們編寫一個SQL存儲過程,在存儲過程中我們顯式地在SELECT語句中使用UR隔離級別。

創(chuàng)建一個存儲過程,保存為LOCKS.SQL,輸出結果如下:

CREATE PROCEDURE locks()

LANGUAGE SQL

BEGIN

declare c1 cursor for select * from staff with UR;

open c1;

while 1=1 do ——注:死循環(huán)

end while;

END @

為了方便抓住鎖信息,我們在這個存儲過程的結尾處使用了一個死循環(huán)。利用一個命令窗口運行存儲過程,輸出結果如下:

C:\ >db2 –td@ -vf locks.sql

C:\ >db2 "call locks()"

再打開一個新的窗口,得到在STAFF表上的當前鎖信息,輸出結果如下:

C:\>db2pd -db sample -locks show detail

Locks:

Address TranHdl Lockname Type Mode Sts Owner Dur HldCnt Att ReleaseFlg

0x408E0290 2 00020003000000000000000054 Table .IS G 2 1 0 0x0000 0x00000001

TbspaceID 2 TableID 3

但是會發(fā)現(xiàn)此時在STAFF表上出現(xiàn)的是IS鎖,而不是IN鎖。是什么原因呢?這是因為UR隔離級別允許應用程序存取其他事務的未落實的更改,但是對于只讀和可更新這兩種不同的游標類型,UR的工作方式有所不同。對于可更新的游標,當它使用隔離級別 UR 運行程序時,應用程序會自動使用隔離級別 CS。

在上面的例子當中,雖然顯式地指定了SQL語句的隔離級別是UR,但是,由于在存儲過程中使用的游標是模糊游標(也就是沒有顯式地聲明游標是只讀的還是可更新的),因而系統(tǒng)會默認地將這個模糊游標當成可更新游標處理,存儲過程的隔離級別自動從UR升級為CS。要防止此升級,可以采用以下辦法:

●       修改應用程序中的游標,以使這些游標是非模糊游標。將SELECT語句更改為包括FOR READ ONLY子句。

●       將模糊游標保留在應用程序中,但是預編譯程序或使用BLOCKING ALL和STATIC READONLY YES選項綁定它以允許在運行該程序時將任何模糊游標視為只讀游標。

我們還是使用上面的例子,顯式地將該游標聲明成只讀游標,輸出結果如下:

declare c1 cursor for select * from staff for read only with UR;

此時我們再運行這個存儲過程,并利用DB2PD獲取鎖的情況,輸出結果如下:

c:\> db2pd -db sample -locks show locks

Locks:

Address TranHdl Lockname Type Mode Sts Owner Dur HldCnt Att ReleaseFlg

0x408E07E0 2 00020003000000000000000054 Table .IN G 2 1 0 0x0000 0x00000001

TbspaceID 2 TableID 3

-注:可以看到STAFF表上出現(xiàn)的鎖是IN鎖。

從上面的例子中我們可以看到:“未提交讀(UR)”隔離級別允許應用程序訪問其他事務的未提交的更改。除非其他應用程序嘗試刪除或改變該表,否則該應用程序也不會鎖定正讀取的行而使其他應用程序不能訪問該行。對于只讀和可更新的游標,“未提交的讀”的工作方式有所不同。

如果使用這種隔離級別,那么對于只讀操作不加行鎖。典型的只讀操作包括:               SELECT語句的結果集只讀(比如語句中包括ORDER BY子句);定義游標時指明起為FOR FETCH ONLY或FOR READ ONLY。

該隔離級別可以改善應用程序的性能,同時可以達到最大程度的并發(fā)性。但是,應用程序的數據完整性將受到威脅。如果需要讀取未提交的數據,該隔離級是唯一選擇。

使用“未提交的讀”,可能出現(xiàn)不可重復讀行為和幻像讀現(xiàn)象。“未提交讀”隔離級別最常用于只讀表上的查詢,或者在僅執(zhí)行選擇語句且不關心是否可從其他應用程序中看到未提交的數據時也最常用。

以上我們所講的隔離級別的加鎖范圍和持續(xù)時間都是針對讀操作而言的。對于更改操作,被修改的行上會被加上X鎖,無論使用何種隔離級別,X鎖都直到提交或回滾之后才會被釋放。

6.1.5  隔離級別加鎖示例講解

假設有一張表EMP1,表中有42條記錄,我們使用FOR READ ONLY分別在UR、CS、RS和RR隔離級別下加鎖。

EMP1表在本章后續(xù)的內容中也會使用到,其創(chuàng)建過程如下:

C:\> db2 "create table emp1 like employee"

C:\> db2 "insert into emp1 select * from employee"

我們使用EMP1表中JOB字段內容為'CLERK'的數據,輸出結果如下:

C:\>db2 +c select empno,job,salary from emp1 where job='CLERK'  for read only

EMPNO  JOB      SALARY

------ -------- -----------

000120 CLERK       49250.00

000230 CLERK       42180.00

000240 CLERK       48760.00

000250 CLERK       49180.00

000260 CLERK       47250.00

000270 CLERK       37380.00

200120 CLERK       39250.00

200240 CLERK       37760.00

  8 條記錄已選擇。

在上面的SQL語句中,我們從表的42條記錄中返回8條記錄。下面我們分別看看這條語句在不同的隔離級別下加鎖的情況:

●       UR隔離級別,輸出結果如下:

C:\>db2 +c select empno,job,salary from emp1 where job='CLERK'  for read only with ur

EMPNO  JOB        SALARY

------ -------- -----------

000120 CLERK       49250.00

000230 CLERK       42180.00

000240 CLERK       48760.00

000250 CLERK       49180.00

000260 CLERK       47250.00

000270 CLERK       37380.00

200120 CLERK       39250.00

200240 CLERK       37760.00

  8 條記錄已選擇。

在另外一個窗口中使用“db2 get snapshot for locks on sample”命令監(jiān)控,發(fā)現(xiàn)在UR隔離級別下,在表上有一個IN鎖,沒有加任何行鎖。

●       CS隔離級別,輸出結果如下:

C:\>db2 +c declare c1 cursor for select empno,job,salary from emp1  where job='CLERK'  for read only with CS

C: \>db2 +c open c1

C: \>db2 +c fetch c1

EMPNO  JOB        SALARY

------ -------- -----------

000120 CLERK       49250.00

  1 條記錄已選擇。

在另外一個窗口中使用“db2 get snapshot for locks on sample”命令監(jiān)控,發(fā)現(xiàn)在CS隔離級別下,共有兩個鎖:在表上有一個IS鎖,在行上有一個NS鎖。

●       RS隔離級別,輸出結果如下:

C:\>db2 +c select empno,job,salary from emp1 where job='CLERK'  for read only with RS

EMPNO  JOB      SALARY

------ -------- -----------

000120 CLERK       49250.00

000230 CLERK       42180.00

000240 CLERK       48760.00

000250 CLERK       49180.00

000260 CLERK       47250.00

000270 CLERK       37380.00

200120 CLERK       39250.00

200240 CLERK       37760.00

  8 條記錄已選擇。

在另外一個窗口中使用“db2 get snapshot for locks on sample”命令監(jiān)控,發(fā)現(xiàn)在RS隔離級別下,共有9個鎖:在表上有一個IS鎖,在讀取的8行上分別有1個NS鎖。

●       RR隔離級別,輸出結果如下:

C:\>db2 +c select empno,job,salary from emp1 where job='CLERK'  for read only with RR

EMPNO  JOB       SALARY

------ -------- -----------

000120 CLERK     49250.00

000230 CLERK     42180.00

000240 CLERK     48760.00

000250 CLERK     49180.00

000260 CLERK     47250.00

000270 CLERK     37380.00

200120 CLERK     39250.00

200240 CLERK     37760.00

  8 條記錄已選擇。

在另外一個窗口中使用“db2 get snapshot for locks on sample”命令監(jiān)控,發(fā)現(xiàn)在RR隔離級別下,分為兩種情況:

如果該SQL語句使用全表掃描,那么即使只讀取了8行,也會在整個表上加一個S鎖,輸出結果如下:

C:\>dynexpln -d sample -q  "select empno,job,salary from emp1 where job='CLERK'

 for read only with rr" –t

Access Table Name = DB2ADMIN.EMP1  ID = 3,12

|  #Columns = 2

|  Relation Scan --注:全表掃描

|  |  Prefetch: Eligible

|  Isolation Level: Repeatable Read --注:RR隔離級別

|  Lock Intents

|  |  Table: Share --注:整個表上加S鎖

|  |  Row  : None

|  Sargable Predicate(s)

|  |  #Predicates = 1

|  |  Return Data to Application

|  |  |  #Columns = 3

Return Data Completion

End of section

如果創(chuàng)建索引,并進行索引掃描,那么表上加IS鎖,讀取的每行上加S鎖。所以對于RR隔離級別來說,為了保證并發(fā),盡可能創(chuàng)建合理的索引以減少加鎖的范圍,輸出結果如下:

C:\>db2 create index job on DB2ADMIN.emp1(job)

DB20000I  SQL命令成功完成。

C:\>db2 runstats on table DB2ADMIN.emp1 and indexes all

DB20000I  RUNSTATS命令成功完成。

C:\>dynexpln -d sample -q  "select empno,job,salary from emp1 where job='CLERK'

 for read only with rr" -t

Access Table Name = DB2ADMIN.EMP1  ID = 3,12

|  Index Scan:  Name = DB2ADMIN.JOB  ID = 1 --注:索引掃描

|  |  Regular Index (Not Clustered)

|  |  Index Columns:

|  |  |  1: JOB (Ascending)

|  #Columns = 2

|  #Key Columns = 1

|  |  Start Key: Inclusive Value

|  |  |  |  1: 'CLERK   '

|  |  Stop Key: Inclusive Value

|  |  |  |  1: 'CLERK   '

|  Data Prefetch: Eligible 0

|  Index Prefetch: None

|  Isolation Level: Repeatable Read --注:RR隔離級別

|  Lock Intents

|  |  Table: Intent Share --注:表上加IS鎖

|  |  Row  : Share --注:行上加S鎖

|  Sargable Predicate(s)

|  |  Return Data to Application

|  |  |  #Columns = 3

Return Data Completion

End of section

6.1.6  隔離級別摘要

表6-1按不期望的結果概述了幾個不同的隔離級別。

表6-1  隔離級別摘要

隔離級別

訪問未提交的數據

不可重復讀

幻像讀現(xiàn)象

可重復讀(RR)

不可能

不可能

不可能

讀穩(wěn)定性(RS)

不可能

不可能

可能

游標穩(wěn)定性(CS)

不可能

可能

可能

未提交讀(UR)

可能

可能

可能

表6-2提供了簡單的試探方法,以幫助您為應用程序選擇初始隔離級別。首先考慮表中列示的方法,并參閱先前對影響各隔離級別因素的討論,可能會找到另一個更適合的隔離級別。

表6-2  選擇隔離級別的準則

應用程序類型

需要高數據穩(wěn)定性

需要高數據穩(wěn)定性

讀寫事務

RS

CS

只讀事務

RR 或 RS

UR

為避免應用程序出現(xiàn)用戶無法容忍的現(xiàn)象,必須為其選擇適當的隔離級別。在不同隔離級別下,應用程序鎖定或釋放資源需要不同的CPU和內存資源,所以隔離級別不但影響應用程序之間的隔離程度,還可能影響應用程序的個別性能特征。潛在的鎖等待情況也會隨隔離級別的不同而不同。

因為隔離級別確定訪問數據時如何鎖定數據并使數據不受其他進程影響,所以您在選擇隔離級別時應該平衡并行性和數據完整性需求。您指定的隔離級別在工作單元運行期間生效。

選擇正確的隔離級別

使用的隔離級別不僅影響數據庫的并發(fā)性,而且影響并發(fā)應用程序的性能。通常,使用的隔離級別越嚴格,并發(fā)性就越小,某些應用程序的性能可能會隨之越低,因為它們要等待資源上的鎖被釋放。那么,如何決定要使用哪種隔離級別呢?最好的方法是先確定哪些現(xiàn)象是不可接受的,然后選擇能夠防止這些現(xiàn)象發(fā)生的隔離級別。以下列舉了各種隔離級別的適用情況:

●       如果正在執(zhí)行大型查詢,而且不希望并發(fā)事務所做的修改導致查詢的多次運行返回不同的結果,則使用可重復讀隔離級別。

●       如果希望在應用程序之間獲得一定的并發(fā)性,還希望限定的行在事務執(zhí)行期間保持穩(wěn)定,則使用讀穩(wěn)定性隔離級別。

●       如果希望獲得最大的并發(fā)性,同時不希望查詢看到未提交的數據,則使用游標穩(wěn)定性隔離級別。

●       如果正在只讀的表/視圖/數據庫上執(zhí)行查詢,或者并不介意查詢是否返回未提交的數據,則使用未提交讀隔離級別。

設置隔離級別

盡管隔離級別控制事務級上的行為,但實際上它們是在應用程序級被指定的:

●       對于嵌入式SQL應用程序,在預編譯時或在將應用程序綁定到數據庫(如果使用延遲綁定)時指定隔離級別。在這種情況下,使用PRECOMPILE或BIND命令的ISOLATION選項來設置隔離級別。

●       對于開放數據庫連接(ODBC)和調用級接口(Call Level Interface,CLI)應用程序,隔離級別是在應用程序運行時通過調用指定了SQL_ATTR_TXN_ISOLATION連接屬性的SQLSetConnectAttr()函數進行設置的。另外,也可以通過指定DB2CLI.INI配置文件中的TXNISOLATION關鍵字的值來設置ODBC/CLI應用程序的隔離級別;但是,這種方法不夠靈活,不能像第一種方法那樣為一個應用程序中的不同事務修改隔離級別。

●       對于Java數據庫連接(JDBC)和SQLJ應用程序,隔離級別是在應用程序運行時通過調用DB2的JAVA.SQL連接接口中的“setTransactionIsolation()”方法設置的。

當沒有使用這些方法顯式指定應用程序的隔離級別時,默認使用游標穩(wěn)定性(CS)隔離級別。這個默認設置被應用于從命令行處理程序(CLP)執(zhí)行的DB2 命令、SQL語句和腳本,以及嵌入式SQL、ODBC/CLI、JDBC和SQLJ應用程序。因此,也可以為從CLP執(zhí)行的操作(以及傳遞給DB2 CLP進行處理的腳本)指定隔離級別。在這種情況下,隔離級別是通過在建立數據庫連接之前在CLP中執(zhí)行CHANGE ISOLATION命令設置的,輸出結果如下:

C:\pp>db2 change isolation to ur

DB21027E  當連接至數據庫時未能更改隔離級別。

C:\pp>db2 connect reset

DB20000I  SQL命令成功完成。

C:\pp>db2 change isolation to ur

DB21053W  當連接至不支持 UR 的數據庫時,會發(fā)生自動升級。

DB20000I  CHANGE ISOLATION命令成功完成。

在DB2 V7.1及更高版本中,能夠指定特定查詢所用的隔離級別,方法是在SELECT SQL語句中加上WITH [RR | RS | CS | UR]子句。大家可以看到,本章前面的示例均使用這種方法舉例。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品大片免费观看| 国产视频自拍一区| 最新日韩在线视频| 在线一区欧美| 亚洲国产欧美一区二区三区丁香婷| 国产精品福利在线| 欧美日韩国产小视频| 久久久青草婷婷精品综合日韩| 亚洲人线精品午夜| 亚洲美女中出| 国产婷婷一区二区| 国产欧美日本| 国语自产在线不卡| 亚洲第一页在线| 亚洲日本va午夜在线电影| 欧美成人一区二免费视频软件| 99精品欧美一区| 亚洲一区二区视频| 欧美一区午夜视频在线观看| 欧美激情网站在线观看| 美国十次成人| 国产精品美女一区二区在线观看| 国产精品一区二区久激情瑜伽| 国产精品入口尤物| 91久久午夜| 国产精品欧美激情| 在线观看欧美日韩| 一区二区三欧美| 久久另类ts人妖一区二区| 欧美激情国产高清| 亚洲欧美日韩精品久久久久| 亚洲欧美一区二区三区在线| 亚洲电影免费观看高清完整版在线观看| 激情成人在线视频| 亚洲欧美日韩高清| 亚洲精品在线视频| 欧美精品大片| 亚洲乱码精品一二三四区日韩在线| 一本色道久久88精品综合| 午夜视频在线观看一区二区三区| 乱人伦精品视频在线观看| 亚洲一区二区高清| 亚洲高清色综合| 久久久久99| 伊人激情综合| 久久视频在线免费观看| 亚洲一区二三| 亚洲精品国产拍免费91在线| 欧美激情四色| 欧美黄色免费| 亚洲一区区二区| 亚洲欧美日韩综合| 黑丝一区二区三区| 影音先锋在线一区| 欧美激情自拍| 国产精品美女久久久久久2018| 亚洲欧美日韩国产成人| 欧美在线免费视屏| 亚洲激情专区| 亚洲一级片在线观看| 亚洲永久网站| 在线观看欧美成人| 亚洲精品日韩久久| 国产精品一区二区女厕厕| 欧美成人69av| 国产精品区一区二区三区| 欧美一二三视频| 亚洲日本欧美天堂| 午夜在线精品| 亚洲免费观看视频| 欧美一区二区视频在线观看| 亚洲欧洲精品一区二区| 亚洲一区二区三区四区在线观看| 韩国一区电影| 亚洲欧美国产日韩天堂区| …久久精品99久久香蕉国产| 亚洲一区二区久久| 一本色道久久综合亚洲精品婷婷| 亚洲欧美另类在线观看| 欧美视频久久| 亚洲激情另类| 亚洲愉拍自拍另类高清精品| 99re8这里有精品热视频免费 | 国产精品99久久久久久白浆小说| 亚洲香蕉成视频在线观看| 亚洲自拍16p| 亚洲国产精品电影| 久久久国产91| 国产一区激情| 久久久久久久一区| 欧美激情1区2区3区| 亚洲精品久久久久| 欧美另类99xxxxx| 中日韩视频在线观看| 国产精品揄拍一区二区| 午夜一区二区三区不卡视频| 久久久最新网址| 在线综合亚洲欧美在线视频| 国产精品久久久久久久久久ktv| 亚洲午夜久久久| 老鸭窝亚洲一区二区三区| 亚洲欧美日韩国产综合精品二区| 国户精品久久久久久久久久久不卡| 久久久久综合网| 亚洲伦理在线观看| 美女免费视频一区| 午夜精彩视频在线观看不卡| 黄色欧美成人| 国产精品日韩欧美一区| 久久免费精品视频| 欧美伊久线香蕉线新在线| 亚洲激情成人| 欧美大片在线影院| 久久久91精品国产一区二区精品| 欧美精品一区二区三区在线播放| 亚洲精品在线免费观看视频| 欧美xart系列高清| 久久久免费精品视频| 亚洲一区二区视频在线| 在线观看视频日韩| 国产欧美日韩三级| 欧美专区福利在线| 亚洲人成在线观看网站高清| 最新国产精品拍自在线播放| 久久综合九色综合久99| 久久精品国产99国产精品| 亚洲图片欧洲图片av| 亚洲一区二区三区免费视频| 这里只有精品丝袜| 亚洲婷婷国产精品电影人久久 | 一本色道久久综合亚洲二区三区| 欧美freesex8一10精品| 国模精品一区二区三区| 一区二区三区精品| 国产欧美精品一区aⅴ影院| 久久久久久久网| 欧美激情精品久久久久久免费印度 | 亚洲高清中文字幕| 国产精品久久一区主播| 亚洲精品日韩在线观看| 久久精彩视频| 尤物九九久久国产精品的特点| 久久精品网址| 欧美日本成人| 国产日韩欧美在线播放不卡| 在线不卡a资源高清| 欧美日韩国产色视频| 欧美性猛交99久久久久99按摩 | **欧美日韩vr在线| 蜜臀91精品一区二区三区| 欧美日韩一区自拍| 欧美激情一区二区三区在线| 亚洲精品在线视频| 久久婷婷一区| 国产精品私拍pans大尺度在线 | 亚洲国产婷婷香蕉久久久久久99| 亚洲精品网站在线播放gif| 久久午夜av| 红桃av永久久久| 久久精品亚洲热| 欧美日本中文字幕| 久久久亚洲人| 在线观看日韩av先锋影音电影院| 国产日韩欧美一区二区| 午夜亚洲福利| 一区二区三区精品久久久| 欧美日韩亚洲三区| 亚洲一区二区伦理| 性欧美videos另类喷潮| 激情五月综合色婷婷一区二区| 久久久精品日韩欧美| 亚洲图中文字幕| 久久精品一本| 免费日本视频一区| 一区二区三区蜜桃网| 午夜在线精品偷拍| 亚洲欧洲在线看| 性欧美超级视频| 日韩视频在线一区二区三区| 亚洲欧美国产三级| 亚洲精品日韩在线观看| 午夜国产不卡在线观看视频| 亚洲日韩视频| 久久久精品动漫| 午夜亚洲伦理| 欧美日韩国产综合新一区| 久久女同互慰一区二区三区| 欧美网站在线观看| 亚洲国产欧美不卡在线观看| 亚洲欧美不卡| 亚洲一区二区三区精品在线| 久久久久久电影| 久久精品卡一| 韩日精品在线| 亚洲免费观看视频| 亚洲毛片网站| 欧美精品一区二区三区蜜臀| 91久久极品少妇xxxxⅹ软件| 久久精品国产96久久久香蕉 | 欧美 日韩 国产一区二区在线视频 |