重新整理 mysql 基礎篇————— 事務隔離級別[四]

不問前世發表於2021-06-13

前言

簡單介紹一下事務隔離的基本

正文

Read Uncommitted(未提交讀)

這個就是讀未提交。就是說在事務未提交的時候,其他事務也可以讀取到未提交的資料。

這裡舉一個例子,還是前一篇的例子。

假如一個張表A=500,B=300,(500,300)有一個事務a和一個事務b,a事務是給A增加100,然後給B減少100。b事務是給B減少100,給A增加100。

假如步驟如圖所示。

  1. A 讀取到的資料是500。

  2. B讀取到的資料是300。

  3. B讀取到的資料是200。

  4. A讀取到的資料是600

假設a先提交,b後提交。那麼就是b事務提交的最後的結果,A為700,B為200。

反過來,如果是b提交,而a後提交,那麼就是a最後提交的結果,A為600,B為100。

這個時候是3步驟就出現問題了,因為讀取為未提交的事務。

Read Commited(提交讀)

一個事務只能看見自己所做的修改,也就是說一個事務在提交之前,所做的修改其他事務看不見。

這樣同樣會存在問題。

比如說,A B C 分別是10 11 12,有兩個事務,a是給A加一,b是兩次執行,C=A+B。

  1. C=A+B 那麼C就是21。

  2. A=A+1 那麼A就是11

  3. A 事務進行提交,那麼A就是11了。這個時候b事務可以讀取到A。

  4. C=A+B,那麼C等於22了。

這種情況要看是否符合你的需求。比如說,一個資料庫就是一直來計算一些數的總值的。那麼是符合你的需求的。

但是如果是第四步,C=C+B,那麼是可能不符合你的需求的。因為C要計算的是C=A+B+A。也就是C=2*A+B,因為A中間變換了,那麼結果不符合預期是不符的。

這種看需求。

repeatable 可重複讀

該級別保證了同一個事物多次讀取同樣記錄的結果一致。

比如說,上面Read Commited(提交讀)的例子中,兩次讀取A都是一致的,在同一個事物中,多次讀取結果不變。

這裡可能有人會提出另一個疑問,比如說有兩個事務,同樣是事務a和事務b。

疑問如下:

比如A=1

執行過程如下:

因為是可重複讀,那麼第四步A中,A還是1,所以最終A結果是2。

是啊,這樣不就出問題了嗎?是的,如果資料庫像這麼簡單,那麼的確出問題了,因為資料庫在執行過程中會做一些判斷,會給資料加上鎖,有了鎖那麼可能上面第2步,就會阻塞,而去執行第四步了。

鎖,後面介紹。

serializable 可序列化

serializable會在讀取的每一行加上鎖,強制事務序列執行。這裡需要注意的是序列化,並不是說事務一條一條執行。

比如說,事務a只修改A資料,然後事務b只修改B資料,這時候依然是併發的,因為他們資料並不衝突。

序列化,因為加了鎖,所以會變得序列。比如事務a修改A然後修改B,事務b修改B然後修改了A。假如因為a修改了A,給A加了鎖,後面事務b修改了B給B加了鎖。故而a事務在等待B釋放鎖,b事務在等A釋放鎖。故而系統會檢查到死鎖,故而只能執行A或B,然後執行下一個。

下一節,隔離的實現方式。

相關文章