天天看點

什麼是髒讀、不可重複讀、幻讀?髒讀、不可重複讀、幻讀事務隔離級别總結

文章已收錄Github精選,歡迎Star: https://github.com/yehongzhi/learningSummary

髒讀、不可重複讀、幻讀

在現代關系型資料庫中,事務機制是非常重要的,假如在多個事務并發操作資料庫時,如果沒有有效的機制進行避免就會導緻出現髒讀,不可重複讀,幻讀。

髒讀

1、在事務A執行過程中,事務A對資料資源進行了修改,事務B讀取了事務A修改後的資料。

2、由于某些原因,事務A并沒有完成送出,發生了RollBack操作,則事務B讀取的資料就是髒資料。

這種讀取到另一個事務未送出的資料的現象就是髒讀(Dirty Read)。

什麼是髒讀、不可重複讀、幻讀?髒讀、不可重複讀、幻讀事務隔離級别總結

不可重複讀

事務B讀取了兩次資料資源,在這兩次讀取的過程中事務A修改了資料,導緻事務B在這兩次讀取出來的資料不一緻。

這種在同一個事務中,前後兩次讀取的資料不一緻的現象就是不可重複讀(Nonrepeatable Read)。

什麼是髒讀、不可重複讀、幻讀?髒讀、不可重複讀、幻讀事務隔離級别總結

幻讀

事務B前後兩次讀取同一個範圍的資料,在事務B兩次讀取的過程中事務A新增了資料,導緻事務B後一次讀取到前一次查詢沒有看到的行。

幻讀和不可重複讀有些類似,但是幻讀強調的是集合的增減,而不是單條資料的更新。

什麼是髒讀、不可重複讀、幻讀?髒讀、不可重複讀、幻讀事務隔離級别總結

第一類更新丢失

事務A和事務B都對資料進行更新,但是事務A由于某種原因事務復原了,把已經送出的事務B的更新資料給覆寫了。這種現象就是第一類更新丢失。

什麼是髒讀、不可重複讀、幻讀?髒讀、不可重複讀、幻讀事務隔離級别總結

第二類更新丢失

其實跟第一類更新丢失有點類似,也是兩個事務同時對資料進行更新,但是事務A的更新把已送出的事務B的更新資料給覆寫了。這種現象就是第二類更新丢失。

什麼是髒讀、不可重複讀、幻讀?髒讀、不可重複讀、幻讀事務隔離級别總結

事務隔離級别

為了解決以上的問題,主流的關系型資料庫都會提供四種事務的隔離級别。事務隔離級别從低到高分别是:讀未送出、讀已送出、可重複讀、串行化。事務隔離級别等級越高,越能保證資料的一緻性和完整性,但是執行效率也越低。是以在設定資料庫的事務隔離級别時需要做一下權衡,MySQL預設是可重複讀的級别。

讀未送出

讀未送出(Read Uncommitted),是最低的隔離級别,所有的事務都可以看到其他未送出的事務的執行結果。隻能防止第一類更新丢失,不能解決髒讀,可重複讀,幻讀,是以很少應用于實際項目。

讀已送出

讀已送出(Read Committed), 在該隔離級别下,一個事務的更新操作結果隻有在該事務送出之後,另一個事務才可能讀取到同一筆資料更新後的結果。可以防止髒讀和第一類更新丢失,但是不能解決可重複讀和幻讀的問題。

可重複讀

可重複讀(Repeatable Read),MySQL預設的隔離級别。在該隔離級别下,一個事務多次讀同一個資料,在這個事務還沒結束時,其他事務不能通路該資料(包括了讀寫),這樣就可以在同一個事務内兩次讀到的資料是一樣的。可以防止髒讀、不可重複讀、第一類更新丢失、第二類更新丢失的問題,不過還是會出現幻讀。

串行化

串行化(Serializable),這是最高的隔離級别。它要求事務序列化執行,事務隻能一個接着一個地執行,不能并發執行。在這個級别,可以解決上面提到的所有并發問題,但可能導緻大量的逾時現象和鎖競争,通常不會用這個隔離級别。

總結

下面我們對事務的隔離級别和對并發問題的解決情況,請看下圖:

什麼是髒讀、不可重複讀、幻讀?髒讀、不可重複讀、幻讀事務隔離級别總結

這篇文章就講到這裡了,感謝大家的閱讀,希望看完大家能有所收獲!

我是一個努力讓大家記住的程式員。我們下期再見!!!

能力有限,如果有什麼錯誤或者不當之處,請大家批評指正,一起學習交流!