事務的隔離級別最清晰理解與MVCC實現機制

2021-09-11 21:26:11 字數 1680 閱讀 4505

mysql事物的隔離級別包括四種

read_uncommitted  spring實現讀未提交 (髒讀)髒讀

read_committed     spring實現讀已提交 (待解決--不可重複讀+幻讀)不可重複讀

repeatable_read   spring實現可重複讀 (待解決--幻讀)可重複讀

serializable     spring實現序列化(已解決)序列化

mysql預設為不可重複讀,oracle預設為可重複讀

髒讀和序列化使我們最容易理解的.假設現在有a、b兩個事務在執行。

髒讀:在a事務中sql讀取到了b中還沒有進行事務提交的資料。(如果b回滾,那麼a就讀到了錯誤的資料)

不可重複讀(你在乙個事務中不能重複的讀取資料,否則結果出現問題):在a事務中不會讀取到b事務中還沒有提交的資料,避免了髒讀。但是在b事務完成提交後,a事務還沒有完成之前,a又去讀了資料,那麼a讀取的在b提交前後的資料是不一致的。

可重複讀(你在事務中可以重複的讀取資料):a事務在b事務提交前後讀取的資料一致。也就是說如果a事務在b事務提交前讀取了一次資料,那麼即使b已經更改了資料庫,但是a讀取到的,還是b事務提交之前的資料,這種會導致幻讀。

序列化:事務序列化,資料與資料庫一致。

思考:既然我們說可重複讀解決了不可重複讀的問題,也就是說我們在乙個事務中讀取到的資料都是一致的,不會因為別的事務提交的資料導致變化,那是不是就說明我們的事務將該行鎖住了,從而避免了其他行對該行的操作呢?

其實不是的,經測試可以看到,其實資料已經更改了,但是我們讀取的資料依然是以前的資料,這是為什麼呢,這時因為mysql採用了mvcc(多版本併發控制)方式。而這種方式讀取的資料會讀取快照(歷史版本),而不會讀取最新版本,但是insert update delete會對當前版本進行操作。

舉個簡單的例子,如果開啟可重複讀,你在a事務裡兩次讀取乙個資料假設為400,那麼在兩次讀取之間事務b更改了資料減去了50此時資料庫為350,對a的讀取結果為400沒有影響,但是如果你在事務a中再讓資料減去50那麼你再在事務a中查詢資料,資料就變成了300.因為update語句會更新資料。

最後來說說 可重複讀 時mysql採用mvcc的實現機制。

其實挺簡單的。這裡值分析一下select的實現,具體的可以看下面的博文

其實在每行資料有麵還有兩個列隱藏的行,一行是我們事務的版本號,一行是刪除的標誌

那麼我們上面說了,每次做增刪改的時候,這一行的事務版本號就會更新。

而mvcc告訴我們我們查詢出的資料,都必須滿足兩個條件,

a.innodb只會查詢版本早於當前事務版本的資料行(也就是,行的系統版本號小於或等於事務的系統版本號),這樣可以確保事務讀取的行,要麼是在事務開始前已經存在的,要麼是事務自身插入或者修改過的.

b.行的刪除版本要麼未定義,要麼大於當前事務版本號,這可以確保事務讀取到的行,在事務開始之前未被刪除.

只有a,b同時滿足的記錄,才能返回作為查詢結果.

那麼每次連線資料庫的時候開啟事務,他都會給你乙個最新的版本號,假設a事務是讀取,那麼a事務在開啟讀取了一次所有資料,那麼b事務開動增加一條資料,並提交,這時這條資料的事務版本號是高於a事務的事務版本好的,所以a再查詢也是查詢不到b事務提交的版本號的。

參考:

清晰理解Mysql的四種事務隔離級別

基礎知識 事務的基本要素 acid a atomicity 原子性 事務開始後所有操作,要麼全部做完,要麼全部不做,不可能停滯在中間環節 c consistency 一致性 a向b轉賬,不可能a扣了錢,b卻沒收到 i isolation 隔離性 a正在從一張銀行卡中取錢,在a取錢的過程結束前,b不能...

理解MySQL InnoDB事務隔離級別

本文為翻譯的文章,作者ovais.tariq,原文 隔離性是acid性質中很重要的部分,它保證事務以一種可靠的方式進行處理。隔離性確保同時執行的事務不會相互干擾。隔離性保證資料的一致性。如果事務沒有被隔離,那麼某個事務可能會修改其它事務正在讀取的資料,因而產生了資料的不一致。既然我們理解了隔離性是什...

事務隔離級別的理解

資料庫事務的隔離級別有4種,由低到高分別為read uncommitted read committed repeatable read serializable 而且,在事務的併發操作中可能會出現髒讀,不可重複讀,幻讀。下面通過事例一一闡述它們的概念與聯絡。read uncommitted 讀未提...