我們首先來簡單了解一下事務:事務首先是定義一組操作集,這組操作集要么都做,要么都不做。
比如A向B轉賬100元,操作集為 (1)讀取A賬戶金額
(2)A賬戶金額 - 100元
(3)讀取B賬戶金額
(4)B賬戶金額 + 100元
如果這組操作集,沒有都執行完,只執行了幾條語句,就會導致數據庫數據不一致性,錢不翼而飛了。
三級封鎖協議,就是在高並發環境下,有多個事務同時執行,保證數據的一致性。一,二,三級協議分別解決了,丟失修改,讀臟數據,和不可重復讀問題。
1.首先我們來介紹一下基本封鎖類型,就是人為的定義的規則,我們必須先知道規則。
鎖的類型:
X鎖: (Exclusive Locks)排它鎖,簡記為X鎖。
S鎖:(Share Locks)共享鎖,簡記為S鎖。
規則如下:①如果一個事務對 數據A加上了X鎖,則不再允許其他事務加X鎖或者S鎖(兩把鎖都不能加)。
②如果一個事務對 數據A加上了S鎖,那么其他事務不能對該事務加X鎖,可以對事務加S鎖(可以加一把S鎖)。
記住這兩條規則,就可以生成一個鎖的相容矩陣:
一個事務對數據A加上了 X鎖,那么另外一個事務對數據A,不能加X鎖,不能加S鎖。
一個事務對數據A加上了S鎖,那么另外一個事務對數據A,不能加X鎖,可以加S鎖。
2.了解了以上規則之后我們就來看三個案例:T1,T2 表示兩個不同的事務,CPU在調度時,可以分配時間片給T1,T2執行,什么時候執行哪個事務的哪條語句是不確定的。其中R(x)表示從數據庫讀取x,W(x)表示往數據庫寫X。
T1 T2
①時刻 R(A) = 100
②時刻 R(A) = 100
③時刻 A = 100 -10
④時刻 R(A) = 100 - 30
⑤時刻 W(A) = 90
⑥時刻 W(A) = 70
這就出現問題了,明明兩個事務先 減10 ,再減30,總數應該是減40 ,結果為 60,這時候就發生了修改丟失。T1事務對A數據的修改丟失了。
重點來了,重點來了,重點來了!!! 這時候來介紹數據庫封鎖一級協議
協議規則如下:
一個事務對數據修改,需要加上X鎖,直到這個事務結束,才把X鎖釋放。
T1 T2 ①時刻 Lock(A) //請求對A加鎖 ②時刻 R(A) = 100,A = 100 -10 ,W(A) = 90 等待 // 請求修改A,對A加鎖,但是T1加的是X鎖,其他事務不能再加鎖,只能等待 ③時刻 Ulock(A)//釋放X鎖 等待 ④時刻 Lock(A) //獲得A鎖 ⑤時刻 R(A)= 90,A=90-30,W(A)= 60 ⑥時刻 Ulock(A)
以上就是一級協議
3.接下來介紹二級封鎖協議的規則如下:
當一個事務寫數據A時,需要加上X鎖,當一個事務讀數據A時,需要加上S鎖讀完立即釋放S鎖。
例如下面這個讀“臟”數據的 例子,看兩個事務會出現什么問題
T1 T2 ①時刻 Lock(A) ②時刻 R(A) = 100,A = 100 -10,W(A) = 90 ③時刻 R(A) = 90 ④時刻 rollback ⑤時刻 Unlock(A) ⑥時刻 恢復A = 100
T1事務先修改了A數據為90,然后T2事務讀取到了數據90,但是后來T1 回滾了,而T2讀到了錯誤的數據,這稱為讀“臟”數據。
而根據二級封鎖協議規定,在讀數據之前需要請求 S 加鎖,則如下面:
T1 T2 ①時刻 Lock(A) ②時刻 R(A) = 100, A = 100 -10,W(A) = 90 ③時刻 //請求加S鎖,但是此時A加了X鎖,不能加S鎖,只能等待 ④時刻 等待 ⑤時刻 RollBack 等待 Unlock(A) ⑥時刻 恢復A= 100 Lock(A) //獲得S鎖 ⑦時刻 R(A) = 100
Unlock(A)
這樣就解決了讀臟數據的問題。
4.數據庫三級封鎖協議
協議規則如下:
在讀數據的時候,對於請求加S鎖,直到事務結束,才釋放S鎖,而不是讀完立即釋放
首先,我們來看一下,“不可重復讀”的情況,我們假設T1事務的任務就是讀2次數據,且隔5s,只是個假設,意思就是沒有讀完2次A就不算T1事務結束
T1 T2 Lock(A)//請求S鎖 ①時刻 R(A) = 100 Unlock(A) ②時刻 Lock(A)//對A進行修改 ③時刻 R(A)= 100 , A = 100 - 10 ,W(A)= 90 ④時刻 Unlock(A) ⑤時刻 Lock(A) ⑥時刻 R(A)= 90 ⑦時刻 Unlock(A)
這時候A兩次讀的數據不一致,出現了不可重復讀的情況。
根據數據庫三級封鎖協議,協議的規則,修改如下
T1 T2 Lock(A)//請求S鎖 ①時刻 R(A) = 100 ②時刻 等待 //請求對A進行修改(加了S鎖,就不能再加X鎖) ③時刻 等待 ④時刻 R(A)= 100 等待 ⑤時刻 Unlock(A) 等待 ⑥時刻 Lock(A)獲得A數據鎖 ⑦時刻 R(A)= 100 , A = 100 - 10 ,W(A)= 90 ⑧時刻 Unlock(A)
這就解決了不可重復讀問題,以上就是對數據庫三級協議的解釋。