事務隔離級別 髒讀 不可重複讀 幻讀 介紹

2021-10-25 15:51:18 字數 1634 閱讀 6974

事務是現代關係型資料庫的核心之一。在多個事務併發運算元據庫(多執行緒、網路併發等)的時候,如果沒有有效的避免機制,就會出現以下幾種問題:

a事務執行過程中,b事務讀取了a事務的修改。但是由於某些原因,a事務可能沒有完成提交,發生rollback了操作,則b事務所讀取的資料就會是不正確的。這個未提交資料就是髒讀(dirty read)。髒讀產生的流程如下:

b事務讀取了兩次資料,在這兩次的讀取過程中a事務修改了資料,b事務的這兩次讀取出來的資料不一樣。b事務這種讀取的結果,即為不可重複讀(nonrepeatable read)。不可重複讀的產生的流程如下:

不可重複讀有一種特殊情況,兩個事務更新同一條資料資源,後完成的事務會造成先完成的事務更新丟失。這種情況就是大名鼎鼎的第二類丟失更新。主流的資料庫已經預設遮蔽了第一類丟失更新問題(即:後做的事務撤銷,發生回滾造成已完成事務的更新丟失),但我們程式設計的時候仍需要特別注意第二類丟失更新。它產生的流程如下:

可以明顯看出事務a的更新被事務b所覆蓋,更新丟失。

b事務讀取了兩次資料,在這兩次的讀取過程中a事務新增了資料,b事務的這兩次讀取出來的集合不一樣。幻讀產生的流程如下:

這個流程看起來和不可重複讀差不多,但幻讀強調的集合的增減,而不是單獨一條資料的修改。

為了解決上面提及的併發問題,主流關係型資料庫都會提供四種事務隔離級別。

在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別是最低的隔離級別,雖然擁有超高的併發處理能力及很低的系統開銷,但很少用於實際應用。因為採用這種隔離級別只能防止第一類更新丟失問題,不能解決髒讀,不可重複讀及幻讀問題。

這是大多數資料庫系統的預設隔離級別(但不是mysql預設的)。它滿足了隔離的簡單定義:乙個事務只能看見已經提交事務所做的改變。這種隔離級別可以防止髒讀問題,但會出現不可重複讀及幻讀問題。

這是mysql的預設事務隔離級別,它確保同一事務的多個例項在併發讀取資料時,會看到同樣的資料行。這種隔離級別可以防止除幻讀外的其他問題。

這是最高的隔離級別,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀、第二類更新丟失問題。在這個級別,可以解決上面提到的所有併發問題,但可能導致大量的超時現象和鎖競爭,通常資料庫不會用這個隔離級別,我們需要其他的機制來解決這些問題:樂觀鎖和悲觀鎖。

這四種隔離級別會產生的問題如下(網上到處都有,懶得畫了):

很多文章部落格在介紹完這些隔離級別以後,就沒有以後了。讀的人一般會覺得,嗯,是這麼回事,我知道了!

學習乙個知識點,是需要實踐的。比如下面這個常見而又異常嚴重的情況:

圖中是典型的第二類丟失更新問題,後果異常嚴重。我們這裡就以讀已提交(read committed)及以下隔離級別中會出現不可重複讀現象為例。從上面的**可以看出,當事務隔離級別為可重複讀(repeatable read)時可以避免。把testreadcommitted中的read執行緒事務級別調整一下:

實際專案中,通過提示客戶端重做的方式,完美解決了不可重複讀的問題。其他併發問題,也可以通過類似的方式解決。

事務隔離級別與髒讀 幻讀 不可重複讀

我們知道,事務的四大特性是a 原子性 c 一致性 i 隔離性 d 永續性 事務隔離級別就是為了滿足隔離性的機制。在併發場景下,如果沒有一定的處理方式,就會出現髒讀 幻讀 不可重複讀三類問題。髒讀 事務a在執行過程中,修改了某資料,事務b讀取了修改後的資料,然後事務a進行了回滾操作,這個時候事務b讀取...

髒讀 幻讀和不可重複讀 事務隔離級別

1.髒讀 髒讀就是指當乙個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,另外乙個事務也訪問這個資料,然後使用了這個資料。e.g.1.mary的原工資為1000,財務人員將mary的工資改為了8000 但未提交事務 2.mary讀取自己的工資 發現自己的工資變為了800...

事務 髒讀 不可重複讀 幻讀

建立db8資料庫 create database db8 使用db8資料庫 use db8 建立賬戶表 create table account id int primary keyauto increment 賬戶id name varchar 20 賬戶名稱 money double 賬戶餘額 ...