資料庫是乙個共享的資料資源。為了提高使用效率,資料庫基本上都是多使用者的,即允許多個使用者併發地訪問資料庫中的資料,如飛機訂票資料庫系統、銀行儲蓄資料庫系統等。在這樣的系統中,同一時刻並行執行的事務可多達數百個。如果對這種併發訪問不加以控制,就會破壞資料的一致性,出現丟失修改、髒讀和不可重複讀這些問題,如圖20.1所示。
丟失修改
髒讀不可重複讀
t1t2
t1t2
t1t2
讀a=16
讀a=16
做a=a-4
寫回a=12
讀a=16
讀a=16
讀a=12
讀a=16
做a=a-2
寫回a=14
做a=a-3
寫回a=13
撤銷讀a=14
做a=a-1
寫回a=15
(資料庫中最後為15)
(a恢復為16)
(a為12,與資料庫中的16不相同)
圖20.1 併發訪問帶來的3個問題
一、丟失修改(lost update)
兩個事務t1和t2讀入同乙個資料,並修改,t2提交的修改結果覆蓋了t1提交的修改結果,導致t1的修改結果丟失。
例如,如圖20.1所示,考慮飛機訂票系統中的乙個操作序列:
1) 甲售票點(t1事務)讀出某航班的機票餘額a,此時為16張。
2) 乙售票點(t2事務)讀出同一航班的機票餘額a,此時也為16張。
3) 甲售票點賣出3張機票,將機票餘額a修改成13張,寫回資料庫。
4) 乙售票點賣出1張機票,將機票餘額a修改成15張,寫回資料庫。
實際上甲、乙兩個售票點共賣出4張機票,可資料庫中最後顯得僅僅是賣出了1張機票。顯然,這是由於併發訪問所造成的。在上面這種操作序列下,第4)步中乙售票點的修改結果覆蓋了第3)步中甲售票點的修改結果,所以導致了這個錯誤。這就是著名的併發訪問中的飛機訂票問題。
二、髒讀(dirty read)
事務t1更改某一資料,並寫入資料庫,事務t2讀取同一資料,但事務t1由於某種原因被撤銷,此時t1更改過的資料恢復原來的值,使t2讀取到的值與資料庫中的值不相同,只是操作過程中的乙個過渡性的、不再需要的、髒的資料,如圖20.1所示。
三、不可重複讀(non-repeatable read)
事務t1讀取資料後,事務t2執行更改操作,使t1無法再現前一次讀取的結果。不可重複讀包括如下幾種情況。
$$ 事務t1讀取某一資料之後,事務t2對其進行更改,使t1再次讀取該資料時,讀取的結果與上次不同,如圖20.1所示。
$$ 事務t1按一定條件讀取某些資料記錄之後,事務t2刪除了其中部分記錄,使t1按相同的條件再次讀取這些資料記錄時,發現某些記錄不在了。
$$ 事務t1按一定條件讀取某些資料記錄之後,事務t2插入了一些記錄,使t1按相同的條件再次讀取這些資料記錄時,發現增加了某些記錄。
後兩種關於記錄的不可重複讀現象也被稱為幻像讀(phantom read)現象。
產生上述幾種問題的主要原因是由於違反了事務的隔離性原則,發生了事務之間的相互影響。
為了保證併發事務執行的正確性,必須要有一定的機制來保證乙個事務的執行不受另乙個事務的影響。例如,如果在飛機訂票例子中,甲售票點在讀出a之後就控制住a,使乙售票點此時無法讀取a,直到甲售票點更改 a並將a=13寫回資料庫後再解除對a的控制為止。這樣一來,乙售票點的操作就是在甲售票點的基礎上再進行的,就會得出正確的結果a=12,尤其是不會覆蓋甲售票點的更改。
「注意」上述問題中的不可重複讀、髒讀是問題或現象但並非就是錯誤,在某些情況下是可以接受的。例如,有的統計工作涉及的資料量很大,讀到一些髒資料、多讀到幾行或少讀到幾行對統計精度沒多大影響。為了減少系統開銷,可以降低要求。
資料庫併發操作帶來的問題
1 丟失更新 當兩個或多個事物讀入同一資料並修改,會發生丟失更新問題,即後乙個事物更新的結果被前一事務所做更新覆蓋 即當事務a和b同事進行時,事務a對資料已經改變但並未提交時b又對同一資料進行了修改 注意此時資料是a還未提交改變的資料 到時a做的資料改動丟失了 2 不可重複讀 當兩個資料讀取某個資料...
資料庫事務併發帶來的問題 及並行
併發與並行的區別 併發 當有多個執行緒在操作時 如果系統只有乙個cpu 則它根本不可能真正同時進行乙個以上的執行緒,它只能 把cpu執行時間劃分成若干個時間段,再將時間段分配給各個執行緒執行,在乙個時間段的執行緒 執行時,其它執行緒處於掛起狀。這種方式我們稱之為併發 concurrent 並行 當系...
資料庫併發操作會帶來哪些問題及原因
1 丟失更新 當兩個或多個事物讀入同一資料並修改,會發生丟失更新問題,即後乙個事物更新的結果被前一事務所做更新覆蓋 即當事務a和b同事進行時,事務a對資料已經改變但並未提交時b又對同一資料進行了修改 注意此時資料是a還未提交改變的資料 到時a做的資料改動丟失了 2 不可重複讀 當兩個資料讀取某個資料...