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