天天看點

事務隔離并發問題 隔離級别 (圖文詳解)

髒讀 :

有兩個事務 同時 通路資料庫時 , 一個事務 進行 update 操作 , 比如将 age = 20 , 改為了age=30, 這個時候 另一個事務 讀取 age ,就是 讀取到了 30 ,那麼 第一個 事務 并沒有 送出,此時如果進行了 復原 操作 , 那麼 age 仍然 = 20 , 第二個 事務 讀取到的 就是 髒資料。

髒讀的本質就是 : 一個事務使用了另一個事務還沒有送出的資料。

這種隔離級别就是讀未送出(read uncommitted),讀取到了别人未送出的資料,使用 讀已送出(read committed) 隔離級别可以避免髒讀問題出現,讀取别人已經送出的資料。

髒讀(讀未送出)執行個體:

使用 2 個指令行mysql ,模拟多線程(多事務)對同一份資料的髒讀問題

事務隔離并發問題 隔離級别 (圖文詳解)

讀已送出 執行個體:

事務隔離并發問題 隔離級别 (圖文詳解)

不可重複讀 :

同樣有兩個事務對資料庫同時操作, 一個事務 進行 讀操作(第一次讀), 讀取 age = 20, 同時 第二個 事務 修改 age = 30 并且送出了事務 ,第一個事務 又進行了讀取操作, 此時讀取到的 age = 30(第二次讀) ,那麼兩次讀取的結果不一樣,就是 不可重複讀。

不可重複讀的本質就是:一個事務多次讀取資料,這個事務還沒有結束的時候,另一個資料對這份資料做出修改,導緻多次讀取的資料結果不一樣

使用 可重複讀 (repeatable read) 隔離級别可以避免 不可重讀 問題出現,也能避免幻讀問題出現(Mysql),可重複讀 保證了一個事務在沒有送出之前,可以對一份資料重複讀取多次,并且每次讀取的資料都是相同的。

不可重複讀 執行個體 :

***還是剛才上面的讀已送出的圖,雖然避免了讀未送出,但是卻出現了,一個事務還沒有結束,
就發生了 不可重複讀問題***
           
事務隔離并發問題 隔離級别 (圖文詳解)

可重複讀 執行個體 :

事務隔離并發問題 隔離級别 (圖文詳解)

幻讀 :

一個事務對資料庫進行操作,這種操作的範圍是資料庫的全部行,然後第二個事務也在對這個資料庫操作,這種操作可以是插入一行記錄或删除一行記錄,那麼第一個是事務就會覺得自己出現了幻覺,怎麼還有沒有處理的記錄呢? 或者 怎麼多處理了一行記錄呢?

幻讀和不可重複讀有些相似之處 ,但是幻讀更偏向于範圍性的操作,而不可重複度偏向于查詢操作。

可重複讀 執行個體 :(防止了幻讀(mysql))

事務隔離并發問題 隔離級别 (圖文詳解)
***但是請注意,這裡的事務隔離級别是   可重複讀的, 是以不會發生幻讀,
如果 這裡的事務隔離級别是 READ UNCOMMITTED 那麼兩個事務就可以同時對相同的資料庫進行更改,
就會發生幻讀問題***
           

串行化(Serialization): 串行化就是不允許出現多線程模式,也就是不允許多個事務同時對資料庫操作,這樣雖然可以有效避免事務并發問題,但是效率非常非常低下,是以很少會用到。