Posted on 2009-03-16 19:10
Prayer 閱讀(213)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
DB2
1. JDBC的數(shù)據(jù)隔離級(jí)別設(shè)置:
JDBC隔離級(jí)別
|
數(shù)據(jù)庫(kù)隔離級(jí)別
|
數(shù)據(jù)訪問(wèn)情況
|
TRANSACTION_READ_UNCOMMITTED(未提交的讀)Uncommitted Read
|
ur
|
就是俗稱“臟讀”(dirty read),在沒(méi)有提交數(shù)據(jù)時(shí)能夠讀到已經(jīng)更新的數(shù)據(jù)
|
TRANSACTION_READ_COMMITTED (游標(biāo)穩(wěn)定性)Cursor Stability
|
cs
|
在一個(gè)事務(wù)中進(jìn)行查詢時(shí),允許讀取提交前的數(shù)據(jù),數(shù)據(jù)提交后,當(dāng)前查詢就可以讀取到數(shù)據(jù)。update數(shù)據(jù)時(shí)候并不鎖住表
|
TRANSACTION_REPEATABLE_READ (讀穩(wěn)定性)Read Stability
|
rs
|
在一個(gè)事務(wù)中進(jìn)行查詢時(shí),不允許讀取其他事務(wù)update的數(shù)據(jù),允許讀取到其他事務(wù)提交的新增數(shù)據(jù)
|
TRANSACTION_SERIALIZABLE (可重復(fù)的讀)Repeatable Read
|
rr
|
在一個(gè)事務(wù)中進(jìn)行查詢時(shí),不允許任何對(duì)這個(gè)查詢表的數(shù)據(jù)修改。
|
“可重復(fù)的讀”隔離級(jí)別rr
當(dāng)使用可重復(fù)的讀隔離級(jí)別時(shí),在單個(gè)事務(wù)執(zhí)行期間鎖定該事務(wù)引用的所有行。使用這種隔離級(jí)別時(shí),同一事務(wù)多次發(fā)出的同一個(gè) SELECT 語(yǔ)句將始終產(chǎn)生同一結(jié)果;丟失更新、臟讀、不可重復(fù)的讀、幻像都不會(huì)發(fā)生。
使用可重復(fù)的讀隔離級(jí)別的事務(wù)可以多次檢索同一行集,并可以對(duì)它們執(zhí)行任意次操作,直到由提交或回滾操作終止事務(wù);不允許其它事務(wù)執(zhí)行插入、更新或刪除操作,因?yàn)檫@些操作會(huì)在隔離事務(wù)存在期間影響正在被使用的行集。為了確保在“可重復(fù)的讀”隔離級(jí)別下運(yùn)行的事務(wù)所訪問(wèn)的數(shù)據(jù)不會(huì)受其它事務(wù)的負(fù)面影響,所以鎖定了該隔離事務(wù)所引用的每個(gè)行 — 而不是僅鎖定被實(shí)際檢索和/或修改的那些行。因此,如果一個(gè)事務(wù)掃描了 1000 行但只檢索 10 行,則所掃描的 1000 行(而不僅是被檢索的 10 行)都會(huì)被鎖定。
那么在現(xiàn)實(shí)環(huán)境中這個(gè)隔離級(jí)別是如何工作的呢?假定您擁有一家大型旅館,并有一個(gè)網(wǎng)站,該網(wǎng)站按“先到先服務(wù)”的原則接受客戶的房間預(yù)訂。如果您的旅館預(yù)訂應(yīng)用程序是在“可重復(fù)的讀”隔離級(jí)別下運(yùn)行的,當(dāng)客戶檢索某個(gè)日期段內(nèi)的所有可用房間列表時(shí),您將無(wú)法更改那些房間在指定日期范圍內(nèi)的費(fèi)用,而其他客戶也將無(wú)法進(jìn)行或取消將會(huì)更改該列表的預(yù)訂,直到生成該列表的事務(wù)終止為止。(對(duì)于第一個(gè)客戶的查詢所指定范圍之外的任何房間,您都可以更改房?jī)r(jià),其他客戶也都可以進(jìn)行或取消房間預(yù)訂。)
“讀穩(wěn)定性”隔離級(jí)別rs
當(dāng)使用讀穩(wěn)定性隔離級(jí)別時(shí),在單個(gè)事務(wù)執(zhí)行期間,會(huì)鎖定該事務(wù)所檢索的所有行。當(dāng)使用這種隔離級(jí)別時(shí),直到隔離事務(wù)終止之前,其它事務(wù)不能更改隔離事務(wù)讀取的所有行。此外,其它事務(wù)對(duì)其它行所作的更改,在提交之前對(duì)于運(yùn)行在“讀穩(wěn)定性”隔離級(jí)別下的事務(wù)而言是不可見(jiàn)的。因此,當(dāng)使用“讀穩(wěn)定性”隔離級(jí)別時(shí),在同一事務(wù)中多次發(fā)出 SELECT 語(yǔ)句可能會(huì)產(chǎn)生不同的結(jié)果。丟失更新、臟讀和不可重復(fù)的讀都不會(huì)發(fā)生;但是,有可能出現(xiàn)幻像。
使用“可重復(fù)的讀”隔離級(jí)別時(shí),隔離事務(wù)引用的每一行都被鎖定;但是,在“讀穩(wěn)定性”隔離級(jí)別下,只鎖定隔離事務(wù)實(shí)際檢索和/或修改的行。因此,如果一個(gè)事務(wù)掃描了 1000 行但只檢索 10 行,則只有被檢索到的 10 行(而不是所掃描的 1000 行)被鎖定。
那么,這種隔離級(jí)別會(huì)如何改變旅館預(yù)訂應(yīng)用程序的工作方式呢?現(xiàn)在,當(dāng)一個(gè)客戶檢索某個(gè)日期段內(nèi)的所有可用房間列表時(shí),您可以更改旅館中任何房間的房?jī)r(jià),而其他客戶也可以取消在第一個(gè)客戶的查詢所指定的日期段內(nèi)所保留房間的預(yù)訂。因此,如果在終止提交查詢的事務(wù)之前再次生成列表,則產(chǎn)生的新列表中有可能包含新的房?jī)r(jià)或第一次產(chǎn)生列表時(shí)不可用的房間。
“游標(biāo)穩(wěn)定性”隔離級(jí)別cs
當(dāng)使用游標(biāo)穩(wěn)定性隔離級(jí)別時(shí),只要隔離事務(wù)所用的游標(biāo)定位在某一行上,就會(huì)鎖定該游標(biāo)所引用的這一行。所獲取的鎖一直有效,直到游標(biāo)重定位(通常通過(guò)調(diào)用 FETCH 語(yǔ)句)或隔離事務(wù)終止為止。因此,當(dāng)使用這種隔離級(jí)別時(shí),在同一事務(wù)中多次發(fā)出 SELECT 語(yǔ)句可能會(huì)產(chǎn)生不同的結(jié)果。丟失更新和臟讀不會(huì)發(fā)生;但有可能出現(xiàn)不可重復(fù)的讀和幻像。
當(dāng)使用“游標(biāo)穩(wěn)定性”隔離級(jí)別的事務(wù)通過(guò)可更新游標(biāo)從表中檢索行時(shí),在游標(biāo)定位在該行上時(shí),其它事務(wù)不能更新或刪除該行。但是,如果被鎖定的行本身不是用索引訪問(wèn)的,那么其它事務(wù)可以將新的行添加到表,并對(duì)位于被鎖定行前后的行進(jìn)行更新和/或刪除操作。此外,如果隔離事務(wù)修改了它檢索到的任何行,那么在隔離事務(wù)終止之前,即使在游標(biāo)不再位于這個(gè)被修改的行,其它事務(wù)不能更新或刪除該行。
其它事務(wù)在其它行上進(jìn)行的更改,在提交之前對(duì)于使用“游標(biāo)穩(wěn)定性”隔離級(jí)別的事務(wù)是不可見(jiàn)的。缺省情況下,大多數(shù)事務(wù)都使用“游標(biāo)穩(wěn)定性”隔離級(jí)別。
這種隔離級(jí)別對(duì)旅館預(yù)訂應(yīng)用程序有什么影響呢?現(xiàn)在,當(dāng)一個(gè)客戶檢索某個(gè)日期段內(nèi)的所有可用房間列表,然后查看關(guān)于所產(chǎn)生的列表上每個(gè)房間的信息時(shí)(每次查看一個(gè)房間),您可以更改旅館中任何房間的房?jī)r(jià),而其他客戶可以對(duì)任何日期段的任何房間進(jìn)行或取消預(yù)訂;唯一的例外是第一個(gè)客戶當(dāng)前正在查看的房間。當(dāng)?shù)谝粋€(gè)客戶查看列表中另一個(gè)房間的信息時(shí),對(duì)于這個(gè)新房間也是一樣;您現(xiàn)在可以更改第一個(gè)客戶剛才查看的房間的房?jī)r(jià),其他客戶也可以預(yù)訂該房間,但不能對(duì)第一個(gè)客戶當(dāng)前正在查看的房間進(jìn)行這些操作。
“未提交的讀”隔離級(jí)別ur
在使用未提交的讀隔離級(jí)別的情況中,當(dāng)單個(gè)事務(wù)檢索行時(shí),僅當(dāng)另一個(gè)事務(wù)試圖刪除或更改被檢索的行所在的表時(shí),才會(huì)在單個(gè)事務(wù)期間鎖定這些行。因?yàn)樵谑褂眠@種隔離級(jí)別時(shí),行通常保持未鎖定狀態(tài),所以丟失更新、臟讀、不可重復(fù)的讀和幻像都可能會(huì)發(fā)生。
在大多數(shù)情況下,其它事務(wù)對(duì)行所作的更改,在提交或回滾之前對(duì)于使用“未提交的讀”隔離級(jí)別的事務(wù)是可見(jiàn)的。但是,此類事務(wù)不能看見(jiàn)或訪問(wèn)其它事務(wù)所創(chuàng)建的表、視圖或索引,直到那些事務(wù)被提交為止。類似地,如果其它事務(wù)刪除了現(xiàn)有的表、視圖或索引,使用“未提交的讀”隔離級(jí)別的事務(wù)僅當(dāng)進(jìn)行刪除操作的事務(wù)終止時(shí)才能了解這一情況。這種行為有一個(gè)例外:當(dāng)運(yùn)行在“未提交的讀”隔離級(jí)別下的事務(wù)使用可更新游標(biāo)時(shí),該事務(wù)的行為和在“游標(biāo)穩(wěn)定性”隔離級(jí)別下運(yùn)行一樣,并應(yīng)用“游標(biāo)穩(wěn)定性”隔離級(jí)別的約束。
“未提交的讀”隔離級(jí)別通常用于那些訪問(wèn)只讀表的事務(wù)和/或某些執(zhí)行 SELECT 語(yǔ)句的事務(wù),這些語(yǔ)句對(duì)其它事務(wù)的未提交數(shù)據(jù)沒(méi)有負(fù)面效果。
那么這種隔離級(jí)別對(duì)旅館預(yù)訂應(yīng)用程序有什么影響呢?現(xiàn)在,當(dāng)一個(gè)客戶檢索某個(gè)日期段內(nèi)的所有可用房間列表時(shí),您可以更改旅館中任何房間的房?jī)r(jià),而其它客戶也可以對(duì)任何日期段內(nèi)的任何房間進(jìn)行或取消預(yù)訂。此外,如果其它客戶取消了預(yù)訂,即使他們還沒(méi)有終止其事務(wù)并將那些取消提交到數(shù)據(jù)庫(kù),所生成的列表就可以包含這些取消預(yù)訂的房間了。
2. 數(shù)據(jù)庫(kù)之間的差異:
1).Oracle通過(guò)具有意向鎖的多粒度封鎖機(jī)制進(jìn)行并發(fā)控制,保證數(shù)據(jù)的一致性。其DML鎖(數(shù)據(jù)鎖)分為兩個(gè)層次(粒度):即表級(jí)和行級(jí)。通常的DML操作在表級(jí)獲得的只是意向鎖(RS或RX),其真正的封鎖粒度還是在行級(jí);DB2也是通過(guò)具有意向鎖的多粒度封鎖機(jī)制進(jìn)行并發(fā)控制,保證數(shù)據(jù)的一致性。其DML鎖(數(shù)據(jù)鎖)分為兩個(gè)層次(粒度):即表級(jí)和行級(jí)。通常的DML操作在表級(jí)獲得的只是意向鎖(IS,SIX或IX),其真正的封鎖粒度也是在行級(jí);另外,在Oracle數(shù)據(jù)庫(kù)中,單純地讀數(shù)據(jù)(SELECT)并不加鎖,這些都提高了系統(tǒng)的并發(fā)程度,Oracle強(qiáng)調(diào)的是能夠"讀"到數(shù)據(jù),并且能夠快速的進(jìn)行數(shù)據(jù)讀取。而DB2的鎖強(qiáng)調(diào)的是"讀一致性",進(jìn)行讀數(shù)據(jù)(SELECT)時(shí)會(huì)根據(jù)不同的隔離級(jí)別(RR,RS,CS)而分別加 S,IS,IS鎖,只有在使用UR隔離級(jí)別時(shí)才不加鎖。從而保證不同應(yīng)用程序和用戶讀取的數(shù)據(jù)是一致的。
2). 在支持高并發(fā)度的同時(shí),DB2和Oracle對(duì)鎖的操縱機(jī)制有所不同:Oracle利用意向鎖及數(shù)據(jù)行上加鎖標(biāo)志位等設(shè)計(jì)技巧,減小了Oracle維護(hù)行級(jí)鎖的開(kāi)銷,使其在數(shù)據(jù)庫(kù)并發(fā)控制方面有著一定的優(yōu)勢(shì)。而DB2中對(duì)每個(gè)鎖會(huì)在鎖的內(nèi)存(locklist)中申請(qǐng)分配一定字節(jié)的內(nèi)存空間,具體是X鎖 64字節(jié)內(nèi)存,S鎖32字節(jié)內(nèi)存(注:DB2 V8之前是X鎖72字節(jié)內(nèi)存而S鎖36字節(jié)內(nèi)存)。
3). Oracle數(shù)據(jù)庫(kù)中不存在鎖升級(jí),而DB2數(shù)據(jù)庫(kù)中當(dāng)數(shù)據(jù)庫(kù)表中行級(jí)鎖的使用超過(guò)locklist*maxlocks會(huì)發(fā)生鎖升級(jí)。
4). 在Oracle中當(dāng)一個(gè)session對(duì)表進(jìn)行insert,update,delete時(shí)候,另外一個(gè)session仍然可以從Orace回滾段或者還原表空間中讀取該表的前映象(before image); 而在DB2中當(dāng)一個(gè)session對(duì)表進(jìn)行insert,update,delete時(shí)候,另外一個(gè)session仍然在讀取該表數(shù)據(jù)時(shí)候會(huì)處于lock wait狀態(tài),除非使用UR隔離級(jí)別可以讀取第一個(gè)session的未提交的值;所以O(shè)racle同一時(shí)刻不同的session有讀不一致的現(xiàn)象,而 DB2在同一時(shí)刻所有的session都是"讀一致"的。
5). db2缺省下是使用cs級(jí)別,oracle缺省是使用ur