一、引言
1、封鎖技術是目前大多數商用DBMS采用的并發控制技術,封鎖技術通過在數據庫對象上維護鎖來實現并發事務非串行調度的沖突可串行化
2、基于鎖的并發控制的基本思想是:
當一個事務對需要訪問的數據庫對象,例如關系、元組等進行操作之前,要先向系統發出封鎖請求,獲得所訪問的數據庫對象上的鎖,即對數據庫對象進行加鎖來限制并發的其他事務對這些數據對象的訪問
3、DBMS采用的封鎖模式均包括共享鎖和排它鎖,同時采用兩階段封鎖協議來約定鎖的使用,保證并發事務非串行調度的可串行化
二、封鎖模式
由于事務對數據庫對象的操作分為讀操作和寫操作,因此,常用的封鎖模式中也有兩種類型的鎖,一種用于讀,稱作共享鎖,簡稱S鎖,又稱作讀鎖
一種用于寫,稱作排他鎖,簡稱X鎖,又稱作寫鎖
1、共享鎖
(1)若事務T想讀取數據庫對象A而不更新A,事務T必須申請獲得A上的共享鎖
(2)若申請成功,則事務在數據庫對象A上加共享鎖,事務T可以讀A但不能寫A
(3)其他事務只能再對A加共享鎖,而不能加排他鎖
這就保證了其他事務可以讀A,但在事務T釋放A上的共享鎖之前,不能對A作任何更新
2、排他鎖
(1)若事務T不僅要讀取數據庫對象A還要更新A?,事務T必須申請獲得A上的排他鎖
(2)若申請成功,則事務T在數據庫對象A上加排他鎖,事務T不僅可以讀A還能寫A
(3)其他事務不能對A加任何類型的鎖
?這就保證了在事務T釋放A上的排他鎖之前,其它事務不能再讀取和更新A
3、對于任何數據庫對象A,其上只能有一個排他鎖,或者沒有排他鎖而有多個共享鎖,也就是有多個事務可以同時讀取A,但只能有一個事務讀取并更新A
4、為了使并發執行的事務提早執行或提前完成,提高事務的執行效率。如果一個事務T想要讀數據庫對象A并可能更新A,應首先申請A上的一個共享鎖,獲得A上的共享鎖后,友好地對待其他事務,允許其他事務申請并獲得A上的共享鎖,同時讀取A,而僅當事務T準備為A寫入新值時,再申請將加在A上的共享鎖升級為排他鎖。而事務T的鎖升級請求是否會得到滿足,則要看此時數據庫對象A上的加鎖情況
5、在同一數據庫對象上已經被某事務加鎖的情況下,并發控制機制能否同意其他事務的封鎖申請的策略,可用一個鎖相容矩陣來描述
在鎖相容矩陣中,最左邊一列表示在某數據庫對象上事務T1已經獲得的鎖,S為共享鎖,X為排他鎖,—表示沒有加鎖,最上邊一行表示另一事務T2對該數據庫對象發出的封鎖請求,T2的封鎖請求能否被滿足,用矩陣中的Y和N來表示,Y即YES,表示T2申請的鎖與T1已擁有的鎖相容,封鎖請求可以滿足,N即NO,表示事務T2申請的鎖與T1已持有的鎖沖突,T2的封鎖請求被拒絕
6、現在我們知道如何使用鎖了,對于我們上一節所提到的這個非可串行化的調度,如果我們在調度中,當事務對需要訪問的數據庫對象進行操作之前,要先向系統發出封鎖申請,在讀之前申請讀鎖并獲得鎖,在寫之前升級為寫鎖并獲得鎖,寫完釋放鎖。
這里用Slock(A)表示在某數據對象A上加上共享鎖,Xlock(A)表示在A上加上排他鎖,Unlock(A)表示釋放A上的鎖,也稱解鎖。可以發現,雖然我們正確地進行了封鎖操作,但并沒有解決該并發事務的非可串行化問題
三、封鎖協議
1、在利用封鎖技術對并發事務進行操作時,需要對事務何時申請要訪問的數據庫對象上的鎖,何時釋放所獲得的鎖等約定一些規則,即封鎖協議
2、約定不同的規則就形成了各種不同的封鎖協議
3、兩階段封鎖協議是最常用的一種實現可串行化的封鎖協議
四、兩階段封鎖協議
兩階段封鎖協議對事務調度中的封鎖操作的順序進行限制,要求在每個事務中,所有的加鎖操作優先于所有解鎖操作,即每個事務在對數據庫對象進行封鎖時,必須分獲得鎖和釋放鎖兩個階段
1、第一階段是獲得鎖階段,也稱擴展階段
- 在這個階段,事務要申請得到完成事務操作所需要的所有鎖,只能申請鎖,不能釋放鎖
2、第二階段是釋放鎖階段,也稱收縮階段?
- 在這個階段,事務釋放所獲得的所有鎖,不能再申請任何鎖
若事務遵循兩階段封鎖協議,其封鎖操作序列應類似這種形式
先是對需要訪問的各數據對象加鎖,然后再開始釋放鎖,實際應用中,為了便于階段的劃分,通常將釋放鎖階段放在事務結束時的COMMIT或ROLLBACK操作中完成
因此許多DBMS的并發控制機制,采用嚴格的兩階段封鎖協議來實現并發事務的可串行化
3、其協議規則包含如下具體內容
- 事務T在讀一個數據庫對象前,必須獲得該數據庫對象上的讀鎖,如果沒有其他事務擁有這個數據庫對象上的寫鎖,那么事務T的封鎖請求得到滿足,操作繼續執行
- 事務T在更新一個數據庫對象前,必須獲得該數據庫對象上的寫鎖,如果沒有其他事務擁有這個數據庫對象上的讀鎖或寫鎖,那么事務T的封鎖請求得到滿足,操作繼續執行。若事務T已具有該數據庫對象上的讀鎖,則必須將讀鎖升級為寫鎖,也必須獲得該數據庫對象上的寫鎖
- 若事務B的封鎖請求與事務A已獲得的鎖不相容時,事務B將處于等待狀態,直到事務A釋放其所擁有的鎖為止
- 事務所獲得的鎖將一直保持到事務結束才釋放。即直到事務提交或終止且提交或終止日志記錄已被刷新到磁盤后,事務才允許釋放鎖
這就是嚴格封鎖協議的要求
3、前面我們對這個非串行化調度進行的封鎖操作,并沒有解決并發事務的非可串行化問題。若采用嚴格的兩階段封鎖協議,事務T1在讀取數據庫對象X之前,申請并獲得讀鎖,寫數據庫對象之前升級讀鎖為寫鎖,寫后并沒有釋放鎖,然后事務T2對數據庫對象X申請的讀鎖,與事務T1已持有的數據庫對象X上的寫鎖不相容,封鎖請求得不到滿足,事務T2處于等待狀態,事務T1繼續完成對數據庫對象Y的讀寫,事務執行完成,提交后才釋放數據庫對象X和Y上的鎖,事務T2才能夠開始執行,事務T2在事務T1釋放鎖之前被拒絕執行,推遲了將導致非可串行化的操作的執行,調度的執行實際上相當于事務T1先于T2的一個串行調度,實現了并發事務的可串行化
4、對于我們在上一節討論的并發事務帶來的數據不一致問題,比如“臟讀”問題,事務T1在完成之前發生了故障,需撤銷回滾,事務T2讀取了夭折事務T1對X的中間更新結果,是一個臟數據
?
若采用嚴格兩階段封鎖協議進行并發控制,在事務T2因對數據庫對象X申請的讀鎖與事務T1已持有的數據庫對象上的寫鎖不相容而處于等待狀態時,事務T1在完成之前發生了故障,則事務T1終止并撤銷回滾,將X的值恢復為事務開始時的值,事務T1結束才釋放所持有的數據對象X上的鎖,事務T2才能夠開始執行,此時事務T2讀取的是夭折事務T1 ROLLBACK后的值,即事務T1沒執行前的值,是數據庫處于一致性狀態時的值,不再是臟數據?
五、小結
1、封鎖技術通過共享鎖間的相容性,以及排他鎖的排他性,使得并發調度中的非沖突操作并發執行,沖突操作串行執行,實現了沖突可串行化
2、采用封鎖技術進行并發控制的DBMS,在具體實現時使用的鎖類型,除了共享鎖和排他鎖兩種基本鎖外,為了事務能夠高效地并發執行并減少死鎖的發生,還會使用一些其他類型的鎖,形成相應的封鎖策略及對應的鎖相容矩陣,以及采用更能便于應用執行的封鎖協議,而不一定是可串行化的嚴格的兩階段封鎖協議