標籤:style color sp strong 資料 div on 問題 bs
本文主要分析資料庫並發控制的一系列問題。事務是並發控制的基本單位,保證事務ACID的特性是交易處理的重要任務,而並行作業有可能會破壞其ACID特性。
一個資料庫可能擁有多個訪問用戶端,這些用戶端都可以並發方式訪問資料庫。資料庫中的相同資料可能同時被多個事務訪問,如果沒有採取必要的隔離措施,就會導致各種並發問題,破壞資料的完整性。這些問題可以歸結為5類,包括三類資料讀問題(髒讀、幻象讀和不可重複讀取)以及兩類資料更新問題(第一類丟失更新和第二類丟失更新)。下面,我們分別通過執行個體講解引發問題的情境。
一、資料讀取問題
1、髒讀(Dirty Read)
首先用一個例子來說,有這樣一個笑話:一個結巴在飲料店櫃檯前轉悠,老闆很熱情地迎上來:“喝一瓶?”,結巴連忙說:“我…喝…喝…”,老闆麻利地開啟易拉罐遞給結巴,結巴終於憋出了他的那句話:“我…喝…喝…喝不起啊!”。在這個笑話中,飲料店老闆就對結巴進行了髒讀。
讀“髒”資料是指事務A修改某一資料,並將其寫回磁碟,事務B讀取同一資料後,A由於某種原因被除撤消,而此時A把已修改過的資料又恢複原值,B讀到的資料與資料庫的資料不一致,則B讀到的資料就為“髒”資料,即無效的資料。
以存取款為例,來看看髒讀的過程:
時間 |
轉賬事務A |
取款事務B |
T1 |
|
開始事務 |
T2 |
開始事務 |
|
T3 |
|
查詢賬戶餘額為1000元 |
T4 |
|
取出500元把餘額改為500元 |
T5 |
查詢賬戶餘額為500元(髒讀) |
|
T6 |
|
撤銷事務餘額恢複為1000元 |
T7 |
匯入100元把餘額改為600元 |
|
T8 |
提交事務 |
|
在這個情境中,B希望取款500元而後又撤銷了動作,而A往相同的賬戶中轉賬100元,就因為A事務讀取了B事務尚未提交的資料,因而造成賬戶白白丟失了500元。
2、不可重複讀取(Unrepeatable Read)
不可重複讀取是指A事務讀取了B事務已經提交的更改資料。假設A在取款事務的過程中,B往該賬戶轉賬100元,A兩次讀取賬戶的餘額發生不一致:
時間 |
取款事務A |
轉賬事務B |
T1 |
|
開始事務 |
T2 |
開始事務 |
|
T3 |
|
查詢賬戶餘額為1000元 |
T4 |
查詢賬戶餘額為1000元 |
|
T5 |
|
取出100元把餘額改為900元 |
T6 |
|
提交事務 |
T7 |
查詢賬戶餘額為900元(和T4讀取的不一致) |
|
在這個情境中,同一事務的T4時間點和T7時間點讀取賬戶存款餘額不一樣。
3、幻象讀(Phantom Read)
A事務讀取B事務提交的新增資料,這時A事務將出現幻象讀的問題。幻象讀一般發生在計算統計資料的事務中,舉一個例子,假設銀行系統在同一個事務中,兩次統計存款賬戶的總金額,在兩次統計過程中,剛好新增了一個存款賬戶,並存入100元,這時,兩次統計的總金額將不一致:
時間 |
統計金額事務A |
轉賬事務B |
T1 |
|
開始事務 |
T2 |
開始事務 |
|
T3 |
統計總存款數為10000元 |
|
T4 |
|
新增一個存款賬戶,存款為100元 |
T5 |
|
提交事務 |
T6 |
再次統計總存款數為10100元(幻象讀) |
|
如果新增資料剛好滿足事務的查詢條件,這個新資料就進入了事務的視野,因而產生了兩個統計不一致的情況。
幻象讀和不可重複讀取是兩個容易混淆的概念,前者是指讀到了其它已經提交事務的新增資料,而後者是指讀到了已經提交事務的更改資料(更改或刪除),為了避免這兩種情況,採取的對策是不同的,防止讀取到更改資料,只需要對操作的資料添加行級鎖,阻止操作中的資料發生變化,而防止讀取到新增資料,則往往需要添加表級鎖——將整個表鎖定,防止新增資料。
二、資料寫入問題
1、第一類丟失更新
A事務撤銷時,把已經提交的B事務的更新資料覆蓋了。這種錯誤可能造成很嚴重的問題,通過下面的賬戶取款轉賬就可以看出來:
時間 |
取款事務A |
轉賬事務B |
T1 |
開始事務 |
|
T2 |
|
開始事務 |
T3 |
查詢賬戶餘額為1000元 |
|
T4 |
|
查詢賬戶餘額為1000元 |
T5 |
|
匯入100元把餘額改為1100元 |
T6 |
|
提交事務 |
T7 |
取出100元把餘額改為900元 |
|
T8 |
撤銷事務 |
|
T9 |
餘額恢複為1000元(丟失更新) |
|
在這個情境中,A事務在撤銷時,“不小心”將B事務已經轉入賬戶的金額給抹去了。
2、第二類丟失更新
A事務覆蓋B事務已經提交的資料,造成B事務所做操作丟失:
時間 |
轉賬事務A |
取款事務B |
T1 |
|
開始事務 |
T2 |
開始事務 |
|
T3 |
|
查詢賬戶餘額為1000元 |
T4 |
查詢賬戶餘額為1000元 |
|
T5 |
|
取出100元把餘額改為900元 |
T6 |
|
提交事務 |
T7 |
匯入100元 |
|
T8 |
提交事務 |
|
T9 |
把餘額改為1100元(丟失更新) |
|
在這個例子裡,由於支票轉賬事務覆蓋了取款事務對存款餘額所做的更新,導致銀行最後損失了100元,相反如果轉賬事務先提交,那麼使用者賬戶將損失100元。
資料庫原理之事務(二)