DBMS 必須提供併發控制機制,併發控制機制是衡量一個 DBMS 性能的重要標誌之一
併發控制機制的任務:
- 對併發操作進行正確調度
- 保證事務的隔離性
- 保證數據庫的一致性
併發操作帶來的數據不一致性:
- 丟失修改( lost update)
- 不可重複讀( non-repeatable read)
- 讀 “髒 ”數據( dirty read )
1. 丟失修改
丟失修改是指事務1 與事務 2 從數據庫中讀入同一數據並修改,事務 2 的提交結果破壞了事務 1 提交的結果,導致事務 1 的修改被丟失。
2. 不可重複讀
不可重複讀是指事務1 讀取數據後,事務2執行更新操作,使事務1 無法再現前一次讀取結果。
事務 1 讀取某一數據後:
1. 事務 2 對其做了修改,當事務 1 再次讀該數據時,得到與前一次不同的值。
2. 事務 2 刪除了其中部分記錄,當事務1 再次讀取數據時,發現某些記錄神密地消失了。
3. 事務 2 插入了一些記錄,當事務 1 再次按相同條件讀取數據時,發現多了一些記錄。
後兩種不可重複讀有時也稱爲幻影現象( phantom row )
3. 讀 “髒 ”數據
事務 1 修改某一數據,並將其寫回磁盤
事務 2 讀取同一數據後
事務 1 由於某種原因被撤消,這時事務 1 已修改過的數據恢復原值
事務 2 讀到的數據就與數據庫中的數據不一致,是不正確的數據,又稱爲 “髒 ”數據。
8.2 封鎖
一、什麼是封鎖
封鎖就是事務 T 在對某個數據對象(例如表、記錄等)操作之前,先向系統發出請求,對其加鎖
加鎖後事務 T 就對該數據對象有了一定的控制, 在事務 T 釋放它的鎖之前, 其它的事務不能更新此數據對象。
封鎖是實現併發控制的一個非常重要的技術
二、基本封鎖類型
8.3 封鎖協議
在運用 X 鎖和 S 鎖對數據對象加鎖時,需要約定一些規則:封鎖協議( Locking Protocol )
- 何時申請 X 鎖或 S 鎖
- 持鎖時間、何時釋放
- 不同的封鎖協議,在不同的程度上爲併發操
- 作的正確調度提供一定的保證
常用的封鎖協議:三級封鎖協議
1 級封鎖協議
事務 T 在修改數據 R 之前必須先對其加 X 鎖,直到事務結束才釋放
正常結束( COMMIT )
非正常結束( ROLLBACK )
1 級封鎖協議可防止丟失修改
在 1 級封鎖協議中, 如果是讀數據, 不需要加鎖的, 所以它不能保證可重複讀和不讀 “髒 ”數據。
2 級封鎖協議
1 級封鎖協議 +事務 T 在讀取數據 R 前必須先加 S 鎖,讀完後即可釋放 S 鎖
2 級封鎖協議可以防止丟失修改和讀 “髒”數據。
在 2 級封鎖協議中,由於讀完數據後即可釋放 S 鎖,所以它不能保證可重複讀。
3 級封鎖協議
1 級封鎖協議 + 事務 T 在讀取數據 R 之前必須先對其加 S 鎖,直到事務結束才釋放
3 級封鎖協議可防止丟失修改、讀髒數據和不可重複讀。
8.4 活鎖和死鎖
1. 死鎖的預防
( 1)一次封鎖法
要求每個事務必須一次將所有要使用的數據全部加鎖,否則就不能繼續執行一次封鎖法存在的問題:降低併發度
擴大封鎖範圍
將以後要用到的全部數據加鎖,勢必擴大了封鎖的範圍,從而降低了系統的併發度難於事先精確確定封鎖對象
數據庫中數據是不斷變化的,原來不要求封鎖的數據,在執行過程中可能會變成封鎖對象,所以很難事先精確地確定每個事務所要封鎖的數據對象
解決方法:將事務在執行過程中可能要封鎖的數據對象全部加鎖,這就進一步降低了併發度。
( 2)順序封鎖法
順序封鎖法是預先對數據對象規定一個封鎖順序,所有事務都按這個順序實行封鎖。
順序封鎖法存在的問題:
- 維護成本高:
數據庫系統中可封鎖的數據對象極其衆多,並且隨數據的插入、刪除等操作而不斷地變化,要維護這樣極多而且變化的資源的封鎖順序非常困難,成本很高
- 難於實現:
事務的封鎖請求可以隨着事務的執行而動態地決定,很難事先確定每一個事務要封鎖哪些對象,因此也就很難按規定的順序去施加封鎖。
2. 死鎖的診斷與解除允許死鎖發生解除死鎖
由 DBMS 的併發控制子系統定期檢測系統中是否存在死鎖一旦檢測到死鎖,就要設法解除
檢測死鎖:
- 超時法:
如果一個事務的等待時間超過了規定的時限,就認爲發生了死鎖
優點:實現簡單
缺點: 有可能誤判死鎖
時限若設置得太長,死鎖發生後不能及時發現
- 等待圖法:
用事務等待圖動態反映所有事務的等待情況
事務等待圖是一個有向圖 G=(T,U )
T 爲結點的集合,每個結點表示正運行的事務
U 爲邊的集合,每條邊表示事務等待的情況
若 T1 等待 T2,則 T1, T2 之間劃一條有向邊,從 T1 指向 T2
併發控制子系統週期性地(比如每隔 1 min )檢測事務等待圖,如果發現圖中存在迴路,則表
示系統中出現了死鎖。
8.5 併發調度的可串行性
幾個事務的並行執行是正確的,當且僅當其結果與按某一次序串行地執行它們時的結果相同。
這種並行調度策略稱爲可串行化( Serializable)的調度。
可串行性是並行事務正確性的唯一準則
保證併發操作調度正確性的方法
封鎖方法:兩段鎖( Two-Phase Locking ,簡稱 2PL)協議
時標方法
樂觀方法
8.6 兩段鎖協議
兩段鎖協議的內容:
- 1. 在對任何數據進行讀、寫操作之前,事務首先要獲得對該數據的封鎖
- 2. 在釋放一個封鎖之後,事務不再獲得任何其他封鎖。
“兩段 ”鎖的含義
事務分爲兩個階段:
- 第一階段是獲得封鎖,也稱爲擴展階段;
- 第二階段是釋放封鎖,也稱爲收縮階段。
並行執行的所有事務均遵守兩段鎖協議,則對這些事務的所有並行調度策略都是可串行化的。
所有遵守兩段鎖協議的事務,其並行執行的結果一定是正確的,事務遵守兩段鎖協議是可串行化調度的充分條件,而不是必要條件可串行化的調度中,不一定所有事務都必須符合兩段鎖協議。
兩段鎖協議與三級封鎖協議
兩類不同目的的協議
兩段鎖協議
保證併發調度的正確性
三級封鎖協議
在不同程度上保證數據一致性
遵守第三級封鎖協議必然遵守兩段協議
8.7 封鎖的粒度
一、什麼是封鎖粒度
X 鎖和 S 鎖都是加在某一個數據對象上的封鎖的對象 :邏輯單元,物理單元
邏輯單元 : 屬性值、屬性值集合、元組、關係、索引項、整個索引、整個數據庫等
物理單元:頁(數據頁或索引頁) 、物理記錄等
二、選擇封鎖粒度的原則
封鎖的粒度越 大,小,
系統被封鎖的對象 少,多,
併發度 小,高,
系統開銷 小,大,
選擇封鎖粒度:
考慮封鎖機構和併發度兩個因素,對系統開銷與併發度進行權衡:
- 需要處理多個關係的大量元組的用戶事務:以數據庫爲封鎖單位;
- 需要處理大量元組的用戶事務:以關係爲封鎖單元;
- 只處理少量元組的用戶事務:以元組爲封鎖單位
8.7.2 多粒度封鎖
多粒度樹:
- 以樹形結構來表示多級封鎖粒度
- 根結點是整個數據庫,表示最大的數據粒度
- 葉結點表示最小的數據粒度
- 顯式封鎖和隱式封鎖
- 顯式封鎖 : 直接加到數據對象上的封鎖
- 隱式封鎖 : 由於其上級結點加鎖而使該數據對象加上了鎖
- 顯式封鎖和隱式封鎖的效果是一樣的
8.7.3 意向鎖
引進意向鎖( intention lock )目的:
- 提高對某個數據對象加鎖時系統的檢查效率
- 對任一結點加基本鎖,必須先對它的上層結點加意向鎖
- 如果對一個結點加意向鎖,則說明該結點的下層結點正在被加鎖