前言
簡單介紹一下事務隔離的基本
正文
Read Uncommitted(未提交讀)
這個就是讀未提交。就是說在事務未提交的時候,其他事務也可以讀取到未提交的數據。
這里舉一個例子,還是前一篇的例子。
假如一個張表A=500,B=300,(500,300)有一個事務a和一個事務b,a事務是給A增加100,然后給B減少100。b事務是給B減少100,給A增加100。
假如步驟如圖所示。
-
A 讀取到的數據是500。
-
B讀取到的數據是300。
-
B讀取到的數據是200。
-
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。
-
C=A+B 那么C就是21。
-
A=A+1 那么A就是11
-
A 事務進行提交,那么A就是11了。這個時候b事務可以讀取到A。
-
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,然后執行下一個。
結
下一節,隔離的實現方式。