?

數據庫的并發控制

2008-07-14 10:05馬宏強
電腦知識與技術 2008年18期

摘要:事務的并發執行可以顯著提高系統的資源利用率,改善對事務的響應時間,但當多個事務對數據庫進行并發操作時,如不加任何控制,可能會引起數據庫的的數據不一致。本文講述了并發操作引起的異常及如何解決異常問題。

關鍵詞:并發操作;可串行化;兩段鎖協議;死鎖

中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2008)18-2pppp-0c

Database Concurrency Control

MA Hong-qiang

(Zhongwei in Ningxia and public security fire brigade,Zhongwei 750021,China)

Abstract:transactions interleaved concurrency can significantly improve the utilization rate of resources,improve the response time of the Panel, but a number of transactions for concurrent operation of the database, if without any control, may cause the database data inconsistencies. This paper described the concurrent operation caused by abnormal anomalies and how to resolve the problem.

Key words: interleaved concurrency;serializable;Two-Phase Locking;Deadlock

1 概述

數據庫的重要特征是可以為多個用戶提供數據共享。例如飛機定票數據庫系統、銀行數據庫系統等都是多用戶數據庫系統。在這樣的系統中,在同一時刻并行運行的事務數據目可達數百個。數據庫管理系統允許共享的用戶數目是數據庫管理系統重要性能參數據之一。數據庫管理系統(以下簡稱為DBMS)必須提供并發控制機制來協調并發用戶的并發操作以保證并發事務的隔離性,從而達到數據庫的一致性。

事務可以一個一個地串行執行,即每個時刻只有一個事務運行,其他事務必須等到這個事務結束以后方能運行。事務在執行過程中需要不同的資源,有時需要CPU,有時需要存取數據,有時需要I/O,有時需要通信。如果事務串行執行則許多系統資源將處于空閑狀態。因此,為了充分利用系統資源,發揮數據庫共享資源的特點,應該允許多個事務并行地執行。

2 并發操作引起的數據不一致性問題

事務是并發控制的基本單位,具有四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isotation)和持續性(Durability)。這四個特性也簡稱為ACID特性。保證事務ACID特性是DBMS的重要任務,而遭到破壞的原因之一是多個事務對數據庫的并發操作造成的。

下面以飛機訂票系統中的一個活動序列為例,說明并發操作帶來的數據不一致問題。

①甲售票點(甲事務)讀出的某航班的機票余額為A,設A=16;

②乙售票點(乙事務)讀出的同一航班的機票余額為A,也為16;

③甲售票點賣出一張機票,修改余額為A=A-1,所以A為15,把A寫回到數據庫;

④乙售票點也賣出一張機票,修改余額為A=A-1,所以A為15,把A寫回到數據庫;

結果明明賣出兩機票,數據庫中機票余額只減少1。這種情況稱為數據庫的不一致性。這種不一致性是由并發操作引起的。在并發操作情況下,對甲、乙兩個事務的操作序列的調度是隨機的。若按上面的調度序列執行,甲事務的修改就被丟失。這是由于第④步中乙事務修改A并寫回后覆蓋了甲事務的修改。

2.1 不一致類型

仔細分析并發操作帶來的數據不一致性包括三類:丟失修改、不可重復讀和讀“臟”數據。

2.1.1 丟失修改

以下為T1和T2兩個事務的四個時刻的活動序列:

①T1讀A=16。

②T2讀A=16。

③T1將A=A-1寫回,A=15。

④T2將A=A-1寫回,A=15。

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

2.1.2 不可重復讀

以下為T1和T2兩個事務的三個時刻的活動序列:

①T1讀A=50,B=100,計算A+B=150。

②T2讀B=100,計算B=B*2=200,并寫回B=200。

③T1讀A=50,B=200,計算A+B=250。

不可重復讀是指事務T1讀取數據后,事務T2執行更新操作,使T1無法再現前一次讀取結果。具體地講,事可重復讀包括三種情況:

(1)事務T1讀取某一數據后(B=100),事務T2對其做了修改(B=200),當事務T1再次讀該數據時,提到與前一次不同的值(B從100變成了200)。

(2)事務T1按一定條件從數據庫中讀取了某些數據記錄后,事務T2刪除了其中的部分記錄,當T1再次按相同條件讀取數據時,發現某些記錄神秘地消失了。

(3)事務T1按一定條件從數據庫中讀取某數據記錄后,事務T2插入了一些記錄,當T1再次按相同條件讀取數據時,發現多了一些記錄。

后兩種不重復讀有時也稱為幻影現象。

2.1.3 讀“臟”數據

以下為T1和T2兩個事務的三個時刻的活動序列:

①T1讀C=100,計算C=C*2=200,寫回C。

②T2讀C=200。

③ROLLBACK,C恢復為100。

讀“臟”數據是指事務T1修改某一數據,并將其寫回磁盤,事務T2讀取同一數據后(C=200),T1由于某種原因撤銷,其修改作廢,這時T1已修改過的數據就恢復原值(C=100),T2讀到的數據就與數據庫中的數據不一致,則T2讀到的數據就為“臟”數據,即為不正確的數據。

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

3 封鎖是實現并發控制的主要技術

封鎖是實現并發控制的一個非常重要的技術。所謂封鎖就是事務T在對某個數據對象(例如表、記錄等)操作之前,先向系統發出請求,對其加鎖。加鎖后事務T就對該數據對象有了一定的控制,在事務T釋放客觀存在的鎖之前,其他的事務不能更新此數據對象。

基本的封鎖類型有兩種:排它鎖(Exclusive Locks,簡稱X鎖)和共享鎖(Share Locks,簡稱為S鎖)。排它鎖又稱為寫鎖。若事務T對數據對象A加上X鎖,則只允許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)。對封鎖方式規定不同就形成了各種封鎖協議。

3.1 兩段鎖協議

計算機系統對并發事務中并發操作的調度是隨機的,而不同的調度可能會產生不同的結果,那么哪個結果是正確的呢?如果一個事務運行過程中沒有其他事務同時運行,也就是說它沒有受到其他事務的干擾,那么就可以認為該事務的運行結果是正確的。因此將所有事務串行起來的調度策略一定是正確的調度策略。雖然以不同的順序串行執行事務可能會產生不同的結果,但由于不會將數據庫置于不一致的狀態,因此都是正確的。

為了保證并發操作的正確性,DBMS的并發控制機制必須提供一定的手段來保證調度是可串行化的。從理論上講,在某一事務執行時禁止其他事務執行的調度策略一定是可串行化的調度,這也是最簡單的調度策略,但這種方法實際上是不可取的,這使提用戶不能充分共享數據庫資源。目前DBMS普遍采用兩段封鎖方法實現并發操作調度的可串行性,從而保證調度的正確性。

所謂兩段鎖協議是指所有事務必須分兩個階段對數據對象加鎖和解鎖。具體作法如下:

(1)在對任何數據對象進行讀、寫操作之前,首先要申請并獲得對該數據對象的封鎖;

(2)在釋放一個封鎖之后,事務不再申請和獲得任何其他封鎖。

所謂“兩段”鎖的含義是:事務分為兩階段,第一階段是獲得封鎖,也稱為擴展階段。在這階段,事務可以申請獲得任何數據對象上的任何類型的鎖,但是不能釋放任何鎖。第二階段是釋放封鎖,也稱為收縮階段。在這階段,事務可以釋放任何數據對象上的任何類型的鎖,但是不能再申請任何鎖??梢宰C明,若并發執行的所有事務均遵守兩段協議是可串行化調度的充分條件,而不是必要條件。也就是說若并發事務都遵守兩段鎖協議,則對這些事務的任何并發調度都是可串行化的;若對并發事務的一個調度是可串行化的,但不一定所有事務都符合兩段鎖協議。

以下為T1和T2兩個事務的一種活動序列:

①T1事務SLOCK B,讀B=2,賦值于Y(即Y=B=2),XLOCK A。

②T2事務SLOCK A,(由于A被加了X鎖,所以加鎖失?。┑却鼳上鎖的釋放。

③T1事務計算A=Y+1,寫回A=3。

④T1事務UNLOCK B,此時T2事務仍在等待A上鎖的釋放;T1事務UNLOCK A,此時T2事務仍在等待A上鎖的釋放。

⑤T2事務SLOCK A(由于A上鎖已釋放,所以加鎖成功),讀A=3,Y=A,XLOCK B,B=Y+1,寫回B=4,UNLOCK B,UNLOC A。

在這個活動序列中,T1和T2都遵守兩段鎖協議,因此調度是可串行化的。

以下為T1和T2兩個事務的另一種活動序列:

①T1事務SLOCK B,讀B=2,賦值于Y(即Y=B=2),UNLOCK B,XLOCK A。

②T2事務SLOCK A(由于A被加了X鎖,所以加鎖失?。?,等待A上鎖的釋放。

③T1事務計算A=Y+1,寫回A=3,UNLOCK A;此時T2事務仍在等待A上鎖的釋放。

④T2事務SLOCK A(由于A上鎖已釋放,所以加鎖成功),讀A=3,X=A,UNLOC A ,XLOCK B,B=X+1,寫回B=4,UNLOCK B。

在這個活動序列中,T1和T2沒有遵守兩段鎖協議,但調度是可串行化的。以上的兩個例子可以說明若并發執行的所有事務均遵守兩段鎖協議是可串行化調度的充分條件,而不是必要條件。

4 死鎖問題

4.1 死鎖現象

由于兩段鎖協議并不要求事務必須一次將所有要使用的數據對象全部加鎖,因此遵守兩段協議的事務可能發生死鎖。以下為T1和T2兩個事務的一種活動序列:

①T1事務SLOCK B,讀B=2。

②T2事務SLOCK A,讀A=2。

③T1事務XLOCK A(由于A已被T2事務加上S鎖,所以加X鎖失?。?,等待A上鎖的釋放。

④T2事務XLOCK B(由于B已被T1事務加上S鎖,所以加X鎖失?。?,等待B上鎖的釋放。

在這個活動序列中,出現了T1在等待T2,而T2又在等待T1的局面,T1和T2兩個事務永遠不能結束,形成死鎖現象。

死鎖現象在操作系統和一般并行處理中已有了成熟的解決方法。目前在數據庫中解決死鎖現象主要有兩類方法,一類是采取一定措施來預防死鎖的發生;另一類方法是允許發生死鎖,采用一定手段定期診斷系統中有無死鎖,若有則解除之。

4.2 死鎖的預防

在數據庫中,產生死鎖的原因是兩個或多個事務都已封鎖了一些數據對象,然后又都請請求對已被其他事務封鎖的數據對象進行加鎖,從而出現相互死等待。防止死鎖的發生其實就是要破壞產生死鎖的條件。預防死鎖通常有兩種方法:

(1)一次封鎖方法

一次封鎖法要求每個事務必須一次將所有要使用的數據對象全部加鎖,否則就不能繼續執行。一次封鎖雖然可以有效地防止死鎖的發生,但也存在問題:第一,一次就將以后要用到的全部數據對象加鎖,勢必擴大了封鎖的范圍,從而降低了系統的并發度;第二,數據庫中數據是來斷變化的,原來不要求封鎖的數據,在執行過程中可能會變成封鎖對象,所以很難事先精確地確定每個事務所要封鎖的數據對象。

(2)順序封鎖法

順序封鎖法是預先對數據對象規定一個封鎖順序,所有事務都按這個順序實行封鎖。順序封鎖法可以有效地防止死鎖,但也同樣存在問題:第一,數據庫系統中封鎖的數據對象極多,并且隨著數據的插入、刪除等操作不斷地變化,要維護這樣的資源的封鎖順序非常困難,成本太高;第二,事務的封鎖請示可以隨著事務的執行而動態地決定,很難事先確定每一個事務要封鎖哪些數據對象,因此也就很難按規定的順序去施加封鎖。

可見,在操作系統中廣為采用的預防死鎖的策略并不很適合數據庫的特點,因此DBMS在解決死鎖現象普遍采用的是診斷并解除死鎖的方法。

4.3 死鎖的診斷與解除

數據庫系統中診斷死鎖的方法與操作系統類似,一般使用超時法或事務等待圖法。

(1)超時法

如果一個事務的等待時間超過了規定的時限,就認為發生了死鎖。超時法實現簡單,但其不足也很明顯。一是有可能誤判死鎖,事務因為其他原因使等待時間超過時限,系統會誤以為發生了死鎖。二是時限若設置得太長,死鎖發生后不能及時發現。

(2)等待圖法

事務等待圖是一個有向圖G(T,U)。T為結點的集合,每個結點表示正在運行的事務;U為邊的集合,每條邊表示事務等待的情況。若T1等待T2,則T1,T2之間邊一條有向邊,從T1指向T2。事務等待圖動態地反映了所有事務的等待情況。并發控制系統周期性地(例如每隔1分鐘)檢測事務等待圖,如果發現圖中存在回路,則表示系統中出現了死鎖。

系統一但檢測出存在死鎖,就要設法解除。通常采用的方法是選擇一個處理死鎖代價最小的事務,將其撤銷,釋放此事務持有的所有的鎖,使其他事務得以繼續運行下去。當然對于撤消的事務所執行的數據修改操作必須加以恢復。

參考文獻:

[1]Abraham Silberschatz(美),著.楊冬青,譯.數據庫系統概念,機械工業出版社,2002.2.

[2]莊成三.數據庫系統原理及其應用,電子工業出版社,2000.6.

[3]俞盤祥.數據庫系統原理.清華大學出版社,1988.

收稿日期:2008-03-18

作者簡介:馬宏強(1980-),男,寧夏固原人,助理工程師,學士,主要研究領域:計算機開發與應用。

91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合