溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

一文教你快速理解 MySQL 事務隔離級別

發(fā)布時間:2020-07-30 10:12:28 來源:網(wǎng)絡 閱讀:149 作者:wx5d9ed7c8443c3 欄目:編程語言

當數(shù)據(jù)庫上有多個事務同時執(zhí)行的時候,就可能出現(xiàn)問題:

  • 臟讀(dirty read)
  • 不可重復讀(non-repeatable read)
  • 幻讀(phantom read)

為了解決這些問題,就有了“隔離級別”的概念,包括:

  • 讀未提交的(read uncommitted)
  • 讀已提交的(read committed)
  • 可重復讀(repeatable read)
  • 串行化(serializable)

下面我們來解決3個問題:

  1. 臟讀、不可重復讀、幻讀是什么意思?
  2. 每個隔離級別是什么含義?
  3. 事務隔離是怎么實現(xiàn)的?

事務同步問題

(1)臟讀(dirty read)

示例:

一文教你快速理解 MySQL 事務隔離級別

在這個例子中根本不存在 id 為 1,并且 age 為 21 的記錄,事務1讀到了臟數(shù)據(jù)。

這就是臟讀,一個事務中讀到了另一個事務修改但未提交的數(shù)據(jù)。

(2)不可重復讀(non-repeatable read)

示例:

一文教你快速理解 MySQL 事務隔離級別

不可重復讀就是一個事務中讀取2次同一條記錄,但每次讀取的結果不同。

(3)幻讀(phantom read)

示例:

一文教你快速理解 MySQL 事務隔離級別

幻讀就是在一個事務中同樣的查詢條件產生取得的結果不同,有新紀錄產生了。

幻讀其實就是不可重復讀的一個特殊情況。

事務隔離級別

  • 讀未提交的(read uncommitted)?是指一個事務還沒有提交時,它所做的變更能夠被其他事務看到。
  • 讀已提交的(read committed)?是指一個事務只有在提交之后,它所做的變更才能被其他事務看到。
  • 可重復讀(repeatable read)是指一個事務中看到的數(shù)據(jù)始終是一致的。
  • 串行化(serializable)會為記錄加鎖,出現(xiàn)鎖沖突時,后邊的事務必須等待前邊的事務執(zhí)行完成才能繼續(xù)。

下面假設一個場景,看看不同隔離級別時的返回結果。

有一個表 T,有一個int型字段 c,包含一條記錄 1。

一文教你快速理解 MySQL 事務隔離級別

不同隔離級別下的值:

  • 隔離級別為讀未提交的

V1=2,此級別下事務2的更改可以被事務1看到。

V2 和 V3 同樣為 2。

  • 隔離級別為讀已提交的

V1=1,V2=2,此級別下事務2未提交的變更事務1看不到,提交后事務1可以看到。

V3=2。

  • 隔離級別為可重復讀

V1=1,V2=1,此級別下事務1執(zhí)行期間看到的值一致。

V3=2。

  • 隔離級別為串行化

事務2會被鎖住,等待事務1提交。V1=1,V2=1,V3=2。

事務隔離的實現(xiàn)

不同事務可以看到不同的值,這是怎么實現(xiàn)的呢?

有一個重要概念 ”回滾日志”。

MySQL中,每條記錄在更新的時候都會記錄一條回滾操作記錄,通過回滾操作,可以得到以前某一狀態(tài)的值。

例如一個值從1依次修改到4,回滾日志就類似如下的形式:

從1改為2 <- 從3改為2 <- 從4改為3 <- 當前值為4

還有一個重要概念 “視圖 read-view“,事務啟動時就會創(chuàng)建視圖,與回滾日志對應起來。

例如3個事務,產生了3個視圖 A B C,和回滾日志的對應關系如下:

一文教你快速理解 MySQL 事務隔離級別

那么事務A取得的值始終為1,其他事務同理。即使有一個新的線程把值從4改成了5,也對其他事務沒影響。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI