1. 程式人生 > >資料庫併發問題及事物隔離級別問題:髒讀,不可重複讀,幻讀,第一類丟失更新,第二類丟失更新

資料庫併發問題及事物隔離級別問題:髒讀,不可重複讀,幻讀,第一類丟失更新,第二類丟失更新

來源:《spring 4 企業應用開發實戰》

資料庫併發問題:髒讀,不可重複讀,幻讀,第一類丟失更新,第二類丟失更新

一個數據庫,多個客戶端併發訪問資料庫。在資料庫中的相同資料可能被多個事物同時訪問,如果沒有采取必要的隔離措施,就會導致併發問題,破壞資料的完整性。這些問題可以歸結為5類:3類資料庫讀問題,2類資料庫更新問題。

1.髒讀(dirty read)

A事物讀取B事物尚未提交更改的資料,並在這個資料的基礎上操作。如果B事物恰巧回滾,那麼A事物讀取到的事物是根本不被承認的。如下列:

時間 事物A 事物B
T1   開始事物
T2 開始事物  
T3   查詢餘額1000元
T4   取出500元,餘額改為500元
T5 查詢餘額500元(髒讀)  
T6   撤銷事物餘額1000元
T7 匯入100元,餘額改為600元  
T8 提交事物  

在這個場景中B希望取出500元,而後又撤銷了動作,而A往相同賬戶轉入100元,就因為A讀取到了B未提交更改資料,造成賬戶白白丟失500元。(注:在oracal資料庫中,不會發生髒讀的情況

2.不可重複讀(unrepeatable read)

不可重複讀是指:A事物讀取到B事物已提交的更改資料。假設A在取款事物過程中,B往賬戶轉入100元,A兩次讀取到的餘額不一致。

時間 事物A 事物B
T1   開始事物
T2 開始事物  
T3   查詢賬戶餘額為1000元
T4 查詢賬戶餘額位1000元  
T5   取出100元,修改餘額為900元
T6   提交事物
T7 查詢賬戶餘額900元(和T4查詢不一致)  

同一事物中兩次查詢賬戶餘額不一致

3.幻讀(phantom read)

A事物讀取B事物提交的新增資料,這時A事物將出現幻讀

時間 事物A

事物B

T1   開始事物
T2 開始事物  
T3 統計賬戶總存款為10000元  
T4   新增一個存款賬戶,並轉入100元
T5   提交事物
T6 再次統計存款為10100元(幻讀)  

如果新增資料剛好滿足查詢條件,這個資料就會進入事物的視野,因而產生兩次統計結果不一致的情況

注:幻讀和不可重複讀的區別在於前者讀取到的是已提交的新增資料,後者讀取到的是已提交的更新資料(或者刪除的資料)。為了避免這兩種情況,採取的策略是不同的,防止讀到更改操作,只需要對操作資料新增行級鎖,阻止操作中的資料發生變化;而防止讀到新增資料,則往往新增表級鎖--將整張表鎖定,防止新增資料(Oracal通過多版本資料的方式實現)

4.第一類丟失資料更新

A事物撤銷時,覆蓋掉 B事物已提交的更新資料。

時間 事物A

事物B

T1   開始事物
T2 開始事物  
T3 查詢賬戶為1000元  
T4   查詢賬戶為1000元
T5   轉入100元,修改餘額為1100元
T6   提交事物
T7 取出100元,修改餘額為900元  
T8 撤銷事物(或提交事物)  
T9 餘額回覆為1000元(丟失更新)  

A事物在撤銷時,將B事物轉入的100元抹去了

5.第二類丟失更新

A事物覆蓋B事物已提交的資料,造成B事物所有的操作丟失

時間 事物A

事物B

T1   開始事物
T2 開始事物  
T3 查詢賬戶為1000元  
T4   查詢賬戶為1000元
T5   取出100元,修改餘額為900元
T6   提交事物
T7 轉入100元  
T8 提交事物  
T9 修改餘額為1100元(丟失更新)  

6.事物隔離級別及影響