數據庫提供了四種事務隔離級別, 不一樣的隔離級別採用不一樣的鎖類開來實現. 數據庫
在四種隔離級別中,併發
Serializable的級別最高, 性能
Read Uncommited級別最低. ui
大多數數據庫的默認隔離級別爲: Read Commited,如Sql Server , Oracle. spa
少數數據庫默認的隔離級別爲Repeatable Read, 如MySQL InnoDB存儲引擎 .net
即便是最低的級別,也不會出現 第一類 丟失 更新問題 . orm
1. 髒讀(事務修改數據沒提交,另外一個事物提早讀取):髒讀就是指當一個事務正在訪問數據,而且對數據進行了修改,而這種修改尚未提交到數據庫中,這時,另一個事務也訪問這個數據,而後使用了這個數據。 blog
2. 不可重複讀(在一個事務內,屢次讀時,另外一個事務作了修改,到止讀取不一致) :是指在一個事務內,屢次讀同一數據。在這個事務尚未結束時,另一個事務也訪問該同一數據。那麼,在第一個事務中的兩次讀數據之間,因爲第二個事務的修改,那麼第一個事務兩次讀到的的數據多是不同的。這樣就發生了在一個事務內兩次讀到的數據是不同的,所以稱爲是不可重複讀。事務
3. 幻讀 (兩個事物修改): 是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的所有數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,之後就會發生操做第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺同樣。例如,一個編輯人員更改做者提交的文檔,但當生產部門將其更改內容合併到該文檔的主複本時,發現做者已將未編輯的新材料添加到該文檔中。若是在編輯人員和生產部門完成對原始文檔的處理以前,任何人都不能將新材料添加到文檔中,則能夠避免該問題。 ci
4.第一類更新丟失(事務回滾 丟失):
當2個事務更新相同的數據源,若是第一個事務被提交,而另一個事務卻被撤銷,那麼會連同第一個事務所作的跟新也被撤銷。也就是說第一個事務作的跟新丟失了。
5.第二類更新丟失(更新覆蓋 丟失):
第二類更新丟失實在實際應用中常常遇到的併發問題,他和不可重複讀本質上是同一類併發問題,一般他被看作不可重複讀的特例:當2個或這個多個事務查詢一樣的記錄而後各自基於最初的查詢結果更新該行時,會形成第二類丟失更新。由於每一個事務都不知道不知道其餘事務的存在,最後一個事務對記錄作的修改將覆蓋其餘事務對該記錄作的已提交的跟新...
1、爲了處理這些問題,SQL標準定義瞭如下4種事務隔離級別:
READ UNCOMMITTED(未提交讀) 幻想讀、不可重複讀和髒讀都容許。一個會話能夠讀取其餘事務未提交的更新結果,若是這個事務最後以回滾結束,這時的讀取結果就多是不正確的,因此多數的數據庫都不會運用這種隔離級別。
READ COMMITTED(已提交讀) 容許幻想讀、不可重複讀,不容許髒讀。一個會話只能讀取其餘事務已提交的更新結果,不然,發生等待,可是其餘會話能夠修改這個事務中被讀取的記錄,而沒必要等待事務結束,顯然,在這種隔離級別下,一個事務中的兩個相同的讀取操做,其結果可能不一樣。
REPEATABLE READ(可重複讀) 容許幻想讀,不容許不可重複讀和髒讀。在一個事務中,若是在兩次相同條件的讀取操做之間沒有添加記錄的操做,也沒有其餘更新操做致使在這個查詢條件下記錄數增多,則兩次讀取結果相同。換句話說,就是在一個事務中第一次讀取的記錄保證不會在這個事務期間發生改動。SQL Server是經過在整個事務期間給讀取的記錄加鎖實現這種隔離級別的,這樣,在這個事務結束前,其餘會話不能修改事務中讀取的記錄,而只能等待事務結束,可是SQL Server不會阻礙其餘會話向表中添加記錄,也不阻礙其餘會話修改其餘記錄。
SERIALIZABLE(可序列化度) 幻想讀、不可重複讀和髒讀都不容許。在一個事務中,讀取操做的結果是在這個事務開始以前其餘事務就已經提交的記錄,SQL Server經過在整個事務期間給表加鎖實現這種隔離級別。在這種隔離級別下,對這個表的全部DML操做都是不容許的,即要等待事務結束,這樣就保證了在一個事務中的兩次讀取操做的結果確定是相同的。SQL標準所定義的默認事務隔離級別是SERIALIZABLE。
2、Oracle中的隔離級別及實現機制:
Oracle數據庫支持READ COMMITTED 和 SERIALIZABLE這兩種事務隔離級別。因此Oracle不支持髒讀,即Oracle中不容許一個會話讀取其餘事務未提交的數據修改結果,從而防止了因爲事務回滾發生的讀取不正確。
Oracle回滾段(快照),在修改數據記錄時,會把這些記錄被修改以前的結果存入回滾段或撤銷段中。Oracle讀取操做不會阻礙更新操做,更新操做也不會阻礙讀取操做
Oracle缺省的配置是Read Committed隔離級別(也稱爲語句級別的隔離),在這種隔離級別下,若是一個事務正在對某個表執行 DML操做,而這時另一個會話對這個表的記錄執行讀取操做,則Oracle會去讀取回滾段或撤銷段中存放的更新以前的記錄,而不會象SQL Server同樣等待更新事務的結束。
Oracle的Serializable隔離級別(也稱爲事務級別的隔離),事務中的讀取操做只能讀取這個事務開始以前已經提交的數據結果。若是在讀取時,其餘事務正在對記錄執行修改,則Oracle就會在回滾段或撤銷段中去尋找對應的原來未經修改的記錄(並且是在讀取操做所在的事務開始以前存放於回滾段或撤銷段的記錄),這時讀取操做也不會由於相應記錄被更新而等待。
補充 : 基於元數據的 Spring 聲明性事務 :
Isolation[ˌaɪsəˈleɪʃən] 隔離: 屬性一共支持五種事務設置,具體介紹以下:
l , DEFAULT 使用數據庫設置的隔離級別 ( 默認 ) ,由 DBA 默認的設置來決定隔離級別 .
2, READ_UNCOMMITTED 會出現髒讀、不可重複讀、幻讀 ( 隔離級別最低,併發性能高 )
3.,READ_COMMITTED 會出現不可重複讀、幻讀問題(鎖定正在讀取的行)
4,REPEATABLE_READ 會出幻讀(鎖定所讀取的全部行)
5,SERIALIZABLE 保證全部的狀況不會發生(鎖表)
不可重複讀的重點是修改 :
一樣的條件 , 你讀取過的數據 , 再次讀取出來發現值不同了
幻讀的重點在於新增或者刪除
一樣的條件 , 第 1 次和第 2 次讀出來的記錄數不同
Oracle默認事務隔離級別
http://my.oschina.net/kanlianhui/blog/215708?p=1
Oracle隔離級別是:
能讀取已提交的事務,可是存在不可重複讀的問題。默認隔離級別應該是:read committed.
Oracle數據庫支持READ COMMITTED 和 SERIALIZABLE這兩種事務隔離級別。
因此Oracle不支持髒讀
SQL標準所定義的默認事務隔離級別是SERIALIZABLE,可是Oracle 默認使用的是READ COMMITTED
設置隔離級別使用
SET TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]