兩個併發事務同時訪問數據庫表相同的行時,可能存在如下三個問題:sql
一、幻想讀(多個事務可能返回的數據行不一樣insert和delete):事務T1讀取一條指定where條件的語句,返回結果集。此時事務T2插入一行新記錄,剛好知足T1的where條件。而後T1使用相同的條件再次查詢,結果集中能夠看到T2插入的記錄,這條新紀錄就是幻想。數據庫
二、不可重複讀取(多個事務可能返回的數據值不一樣做用update):事務T1讀取一行記錄,緊接着事務T2修改了T1剛剛讀取的記錄,而後T1再次查詢,發現與第一次讀取的記錄不一樣,這稱爲不可重複讀。併發
三、髒讀(行值可能都不一樣):事務T1更新了一行記錄,還未提交所作的修改,這個T2讀取了更新後的數據,而後T1執行回滾操做,取消剛纔的修改,因此T2所讀取的行就無效,也就是髒數據。sqlserver
1、爲了處理這些問題,SQL標準定義瞭如下幾種事務隔離級別:spa
READ UNCOMMITTED 幻想讀、不可重複讀和髒讀都容許。一個會話能夠讀取其餘事務未提交的更新結果,若是這個事務最後以回滾結束,這時的讀取結果就多是不正確的,因此多數的數據庫都不會運用這種隔離級別。.net
READ COMMITTED 容許幻想讀、不可重複讀,不容許髒讀。一個會話只能讀取其餘事務已提交的更新結果,不然,發生等待,可是其餘會話能夠修改這個事務中被讀取的記錄,而沒必要等待事務結束,顯然,在這種隔離級別下,一個事務中的兩個相同的讀取操做,其結果可能不一樣。版本控制
REPEATABLE READ 容許幻想讀,不容許不可重複讀和髒讀。在一個事務中,若是在兩次相同條件的讀取操做之間沒有添加記錄的操做,也沒有其餘更新操做致使在這個查詢條件下記錄數增多,則兩次讀取結果相同。換句話說,就是在一個事務中第一次讀取的記錄保證不會在這個事務期間發生改動。SQL Server是經過在整個事務期間給讀取的記錄加鎖實現這種隔離級別的,這樣,在這個事務結束前,其餘會話不能修改事務中讀取的記錄,而只能等待事務結束,可是SQL Server不會阻礙其餘會話向表中添加記錄,也不阻礙其餘會話修改其餘記錄。server
SERIALIZABLE 幻想讀、不可重複讀和髒讀都不容許。在一個事務中,讀取操做的結果是在這個事務開始以前其餘事務就已經提交的記錄,SQL Server經過在整個事務期間給表加鎖實現這種隔離級別。在這種隔離級別下,對這個表的全部DML操做都是不容許的,即要等待事務結束,這樣就保證了在一個事務中的兩次讀取操做的結果確定是相同的。SQL標準所定義的默認事務隔離級別是SERIALIZABLE。htm
√: 可能出現 ×: 不會出現事務
髒讀 | 不可重複讀 | 幻讀 | ||
Read uncommitted(未受權讀取) | √ | √ | √ | 可能出現roback,update,insert,delete |
Read committed(受權讀取) | × | √ | √ | 可能出現update,insert,delete |
Repeatable read(可重複讀取) | × | × | √ | 可能出現insert,delete |
SNAPSHOT(快照) sqlserver | × | × | × | |
Serializable( 序列化) | × | × | × | 查詢期間,不容許其餘事務insert或delete或update |
2、Oracle中的隔離級別及實現機制:
Oracle數據庫支持READ COMMITTED 和 SERIALIZABLE這兩種事務隔離級別。因此Oracle不支持髒讀,即Oracle中不容許一個會話讀取其餘事務未提交的數據修改結果,從而防止了因爲事務回滾發生的讀取不正確。
Oracle回滾段,在修改數據記錄時,會把這些記錄被修改以前的結果存入回滾段或撤銷段中。Oracle讀取操做不會阻礙更新操做,更新操做也不會阻礙讀取操做,這樣在Oracle中的各類隔離級別下,讀取操做都不會等待更新事務結束,更新操做也不會由於另外一個事務中的讀取操做而發生等待,這也是Oracle事務處理的一個優點所在。
Oracle缺省的配置是Read Committed隔離級別(也稱爲語句級別的隔離),在這種隔離級別下,若是一個事務正在對某個表執行 DML操做,而這時另一個會話對這個表的記錄執行讀取操做,則Oracle會去讀取回滾段或撤銷段中存放的更新以前的記錄,而不會象SQL Server同樣等待更新事務的結束。
Oracle的Serializable隔離級別(也稱爲事務級別的隔離),事務中的讀取操做只能讀取這個事務開始以前已經提交的數據結果。若是在讀取時,其餘事務正在對記錄執行修改,則Oracle就會在回滾段或撤銷段中去尋找對應的原來未經修改的記錄(並且是在讀取操做所在的事務開始以前存放於回滾段或撤銷段的記錄),這時讀取操做也不會由於相應記錄被更新而等待。
設置隔離級別使用 SET TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
三 、MYSQL默認Repeat Read ,在這一級別下,有賴於MVCC(多版本併發控制),就是說數據庫在事務併發的過程當中對數據維護多個版本,使得不一樣的事務對不一樣的數據版本進行讀寫(MVCC的實現參見引用中的文章)。這樣的機制反映在應用中就是,在任什麼時候候對數據庫查詢老是能夠獲得數據庫中最近提交的數據。爲被提交的髒數據被隔離起來,沒法被查詢到,即防止髒讀發生
設置隔離級別使用 SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
四、在SQL Server 2005中,已提交讀隔離級別是創建鏈接時的默認隔離級別。這個級別存在兩種類型:已提交讀和已提交讀快照隔離級別。應用哪一種類型由數據庫選項定義。已提交讀級別會在讀數據以前等待,直到阻塞鎖被釋放。已提交讀快照級別會在數據被其餘事務阻塞時使用行版本控制來讀數據最後一次提交的版本。
設置隔離級別使用 SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SNAPSHOT|IALIZABLE}
轉至:http://www.jb51.net/article/30899.htm