學習筆記——DB併發控制

        在單處理機系統中, 事務的並行執行實際上是這些並行事務的並行操作輪流交叉運行。稱爲交叉併發方式(interleaved concurrency)。雖然單處理機系統中的並行事務並沒有真正地並行運行, 但是減少了處理機的空閒時間, 提高了系統的效率。

一、概述

       事務是併發控制的基本單位, 保證事務的ACID特性是事務處理的重要任務, 而事務的ACID特性可能遭到破壞的原因之一是多個事務對數據庫的併發操作造成的。 爲了保證事務的隔離性和一致性, DBMS需要對併發操作進行正確調度。 這些就是數據庫管理系統中併發控制機制的責任。
       併發操作帶來的數據不一致性包括丟失修改、不可重複讀和讀“髒”數據。

       1)丟失修改:兩個事務T1和T2讀入同一數據並修改,T2提交的結果破壞了T1提交的結果,導致T1的修改被丟失。

       2)不可重複讀:指事務T1讀取數據後,事務T2執行更新操作,使T1無法再現前一次讀取結果。

       3)讀“髒”數據:指事務T1修改某一數據並將其寫回磁盤,事務T2讀取同一數據後,T1由於某種原因被撤銷,這時被T1修改過的數據恢復原值,T2讀到的數據就與數據庫中的數據不一致,則T2讀到的數據就爲“髒”數據,即不正確的數據。

       產生上述三類數據不一致性的主要原因是併發操作破壞了事務的隔離性。併發控制機制就是要用正確的方式調度併發操作,使一個用戶事務的執行不受其他事務的干擾,從而避免造成數據的不一致性。

       併發控制的主要技術有封鎖(locking)、時間戳(timestamp)、樂觀控制法(optimistic scheduler)和多版本併發控制(multi-version concurrency control,MVCC)等。

二、封鎖

       所謂封鎖就是事務T在對某個數據對象例如表、記錄等操作之前,先向系統發出請求,對其加鎖。加鎖後事務T就對該數據對象有了一定的控制,在事務T釋放它的鎖之前,其他事務不能更新此數據對象。

       確切的控制由封鎖的類型決定。基本類型:排他鎖(exclusive locks,簡稱X鎖)和共享鎖(share locks,簡稱S鎖)。

       排他鎖又稱爲寫鎖。若事務T對數據對象A加上X鎖,則只允許T讀取和修改A, 其他任何事務都不能再對A加任何類型的鎖,直到T釋放A上的鎖爲止。這就保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A。

       共享鎖又稱爲讀鎖。若事務T對數據對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖爲止。這就保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。

相容矩陣:

三、封鎖協議

       在運用X鎖和S鎖這兩種基本封鎖對數據對象加鎖時, 還需要約定一些規則。如:何時申請X鎖或S鎖、 持鎖時間、 何時釋放等。 這些規則稱爲封鎖協議(locking protocol)。對封鎖方式制定不同的規則, 就形成了各種不同的封鎖協議。

      一級封鎖協議是指,事務T在修改數據R之前必須先對其加X鎖,直到事務結束才釋放。一級封鎖協議可防止丟失修改,並保證事務T是可恢復的。在一級封鎖協議中,如果僅僅是讀數據而不對其進行修改,是不需要加鎖的,所以它不能保證可重複讀和不讀“髒”數據。

       二級封鎖協議是指,在一級封鎖協議基礎上增加事務T在讀取數據R之前必須先對其加S鎖,讀完後即可釋放S鎖。二級封鎖協議除防止了丟失修改,還可進一步防止讀“髒”數據。在二級封鎖協議中,由於讀完數據後即可釋放S鎖,所以它不能保證可重複讀。

       三級封鎖協議是指,在一級封鎖協議的基礎上增加事務T在讀取數據R之前必須先對其加S鎖,直到事務結束才釋放。三級封鎖協議除了防止丟失修改和讀“髒”數據外,還進一步防止了不可重複讀。

不同級別的封鎖協議和一致性保證:

四、活鎖和死鎖

(1)活鎖:如果事務T1封鎖了數據R,事務T2又請求封鎖R,於是T2等待;T3也請求封鎖R,當T1釋放了 R上的封鎖之後系統首先批准了 T3的請求,T2仍然等待;然後T4又請求封鎖 R,當T3釋放了R上的封鎖之後系統又批准了T4的請求……T2有可能永遠等待。

       避免活鎖:採用先來先服務的策略。當多個事務請求封鎖同一數據對象時,封鎖子系統按請求封鎖的先後次序對事務排隊,數據對象上的鎖一旦釋放就批准申請隊列中第一個事務獲得鎖。

(2)死鎖:如果事務T1封鎖了數據R1,T2封鎖了數據R2,然後T1又請求封鎖R2,因T2已封鎖了R2,於是T1等待T2釋放R2上的鎖;接着T2又申請封鎖R1,因T1已封鎖了 R1,T2等待T1釋放R1上的鎖。這樣就出現了 T1在等待T2,而T2又在等待T1的局面,T1和T2兩個事務永遠不能結束,形成死鎖。

       在數據庫中解決死鎖問題主要有兩類方法,一類方法是採取一定措施來預防死鎖的發生,另一類方法是允許發生死鎖,進行死鎖的診斷與解除。

(3)死鎖的預防:

       防止死鎖的發生其實就是要破壞產生死鎖的條件。預防死鎖通常有以下兩種方法:

       1)一次封鎖法要求每個事務必須一次將所有要使用的數據全部加鎖,否則就不能繼續執行。

         第一,一次就將以後要用到的全部數據加鎖, 勢必擴大了封鎖的範圍, 從而降低了系統的併發度;

         第二, 數據庫中數據是不斷變化的, 原來不要求封鎖的數據在執行過程中可能會變成封鎖對象, 所以很難事先精確地確

         定每個事務所要封鎖的數據對象, 爲此只能擴大封鎖範圍, 將事務在執行過程中可能要封鎖的數據對象全部加鎖, 這就

         進一步降低了併發度。

       2)順序封鎖法是預先對數據對象規定一個封鎖順序,所有事務都按這個順序實施封鎖。

         存在問題,順序很難確定。

       可見,在操作系統中廣爲採用的預防死鎖的策略並不太適合數據庫的特點,因此DBMS在解決死鎖的問題上普遍採用的是診斷並解除死鎖的方法。一般使用超時法或事務等待圖法。

(4)死鎖的診斷與解除

超時法:如果一個事務的等待時間超過了規定的時限,就認爲發生了死鎖。

              超時法實現簡單,但存在缺點:一是有可能誤判死鎖, 如事務因爲其他原因而使等待時間超過時限;系統會誤認爲發

              生了死鎖; 二是時限若設置得太長, 死鎖發生後不能及時發現。

事務等待圖:動態地反映了所有事務的等待情況。併發控制子系統週期性地(比如每隔數秒)生成事務等待圖,並進行檢測。如果發現圖中存在迴路,則表示系統中出現了死鎖。

                

解除死鎖:選擇一個處理死鎖代價最小的事務,將其撤銷,釋放此事務持有的所有的鎖, 使其他事務得以繼續運行下去。當然,對撤銷的事務所執行的數據修改操作必須加以恢復。

             

五、可串行化調度

       定義多個事務的併發執行是正確的,當且僅當其結果與按某一次序串行地執行這些事務時的結果相同,稱這種調度策略爲可串行化(serializable)調度。

       爲了保證併發調度的正確性,DBMS的併發控制機制必須提供一定的手段來保證調度是可串行化的。目前DBMS普遍採用兩段鎖(TwoPhase Locking,簡稱 2PL)協議的方法實現併發調度的可串行性,從而保證調度的正確性。所謂兩段鎖協議是指所有事務必須分兩個階段對數據項加鎖和解鎖。

遵循兩段鎖協議的可串行化調度:

       事務遵守兩段鎖協議是可串行化調度的充分條件, 而不是必要條件。也就是說, 若併發事務都遵守兩段鎖協議, 則對這些事務的任何併發調度策略都是可串行化的; 但是, 若併發事務的一個調度是可串行化的, 不一定所有事務都符合兩段鎖協議。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章