数据库并发控制技术
| 數據庫是一個共享資源,可以提供多個用戶使用。這些用戶程序可以一個一個地串行執行,每個時刻只有一個用戶程序運行,執行對數據庫的存取,其他用戶程序必須等到這個用戶程序結束以后方能對數據庫存取。但是如果一個用戶程序涉及大量數據的輸入/輸出交換,則數據庫系統的大部分時間處于閑置狀態。因此,為了充分利用數據庫資源,發揮數據庫共享資源的特點,應該允許多個用戶并行地存取數據庫。但這樣就會產生多個用戶程序并發存取同一數據的情況,若對并發操作不加控制就可能會存取和存儲不正確的數據,破壞數據庫的一致性,所以數據庫管理系統必須提供并發控制機制。并發控制機制的好壞是衡量一個數據庫管理系統性能的重要標志之一。 DM用封鎖機制來解決并發問題。它可以保證任何時候都可以有多個正在運行的用戶程序,但是所有用戶程序都在彼此完全隔離的環境中運行。 |
| 一、并發控制的預備知識 |
| (1)并發控制概述 |
| 并發控制是以事務(transaction)為單位進行的。 |
| 1、并發控制的單位――事務 |
| 事務是數據庫的邏輯工作單位,它是用戶定義的一組操作序列。一個事務可以是一組SQL語句、一條SQL語句或整個程序。 |
| 事務的開始和結束都可以由用戶顯示的控制,如果用戶沒有顯式地定義事務,則由數據庫系統按缺省規定自動劃分事務。 |
| 事務應該具有4種屬性:原子性、一致性、隔離性和持久性。 |
| (1)原子性 |
| 事務的原子性保證事務包含的一組更新操作是原子不可分的,也就是說這些操作是一個整體,對數據庫而言全做或者全不做,不能部分的完成。這一性質即使在系統崩潰之后仍能得到保證,在系統崩潰之后將進行數據庫恢復,用來恢復和撤銷系統崩潰處于活動狀態的事務對數據庫的影響,從而保證事務的原子性。系統對磁盤上的任何實際數據的修改之前都會將修改操作信息本身的信息記錄到磁盤上。當發生崩潰時,系統能根據這些操作記錄當時該事務處于何種狀態,以此確定是撤銷該事務所做出的所有修改操作,還是將修改的操作重新執行。 |
| (2)一致性 |
| 一致性要求事務執行完成后,將數據庫從一個一致狀態轉變到另一個一致狀態。它是一種以一致性規則為基礎的邏輯屬性,例如在轉賬的操作中,各賬戶金額必須平衡,這一條規則對于程序員而言是一個強制的規定,由此可見,一致性與原子性是密切相關的。事務的一致性屬性要求事務在并發執行的情況下事務的一致性仍然滿足。它在邏輯上不是獨立的,它由事務的隔離性來表示。 |
| (3)隔離性 |
| 隔離性意味著一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的數據對并發的其他事務是隔離的,并發執行的各個事務之間不能互相干擾。它要求即使有多個事務并發執行,看上去每個成功事務按串行調度執行一樣。這一性質的另一種稱法為可串行性,也就是說系統允許的任何交錯操作調度等價于一個串行調度。串行調度的意思是每次調度一個事務,在一個事務的所有操作沒有結束之前,另外的事務操作不能開始。由于性能原因,我們需要進行交錯操作的調度,但我們也希望這些交錯操作的調度的效果和某一個串行調度是一致的。 DM實現該機制是通過對事務的數據訪問對象加適當的鎖,從而排斥其他的事務對同一數據庫對象的并發操作。 |
| (4)持久性 |
| 系統提供的持久性保證要求一旦事務提交,那么對數據庫所做的修改將是持久的,無論發生何種機器和系統故障都不應該對其有任何影響。例如,自動柜員機( ATM)在向客戶支付一筆錢時,就不用擔心丟失客戶的取款記錄。事務的持久性保證事務對數據庫的影響是持久的,即使系統崩潰。正如在講原子性時所提到的那樣,系統通過做記錄來提供這一保證。 |
| DM沒有提供顯式定義事務開始的語句,第一個可執行的SQL語句(除CONNECT語句外)隱含事務的開始,但事務的結束可以由用戶顯式的控制。在DM中以下幾種情況都結束 (正常,非正常)某一事務: |
| (1)當某一連接的屬性設置為自動提交,每執行一條語句都會提交; |
| (2)遇到COMMIT/ROLLBACK語句,便提交/回滾一事務; |
| (3)當系統的 DDL自動提交開關打開時(缺省為打開),遇到DDL語句則自動提交該DDL語句和以前的DML和DDL操作; |
| (4)事務所在的程序正常結束和用戶退出; |
| (5)系統非正常終止時; |
| 說明:DM在配置文件中提供了DDL語句的自動提交開關DDL_AUTO_COMMIT。 當此配置項的值為 1(缺省情況)時,所有DDL語句自動提交;當此配置項的值為0時,除CREATEDATABASE、ALTERDATABASE和CREATESCHEMA語句外的所有DDL語句都不自動提交。 |
| DM中的一致性是以事務為基礎的。DM通過提交和回滾分別用于將對數據庫的修改永久化和廢除,但是無論是提交和回滾,DM保證數據庫在每個事務開始前、結束后是一致的。為了提高事務管理的靈活性,DM提供了設置保存點(SAVEPOINT)語句和回滾到保存點語句。保存點提供了一種靈活的回滾,事務在執行中可以回滾到某個保存點,在該保存點以前的操作有效,而以后的操作被回滾掉。 |
| DM中的事務同樣具有上述4個屬性:原子性、一致性、隔離性和持久性。 |
| 2、并發操作與數據的不一致性 |
| 如果沒有鎖定且多個用戶同時訪問一個數據庫,則當他們的事務同時使用相同的數據時可能會發生問題,導致數據庫中的數據的不一致性。 |
| 一個最常見的并發操作的例子是火車/飛機訂票系統中的訂票操作。例如,在該系統中的一個活動序列: |
| 1、甲售票員讀出某航班的機票張數余額A,設A=16; |
| 2、乙售票員讀出同一航班的機票張數余額A,也是16; |
| 3、甲售票員賣出一張機票,修改機票張數余額A=A-1=15,把A寫回數據庫; |
| 4、乙售票員也賣出一張機票,修改機票張數余額A=A-1=15,把A寫回數據庫。 |
| 結果明明賣出兩張機票,數據庫中機票余額只減少1。 |
| 這種情況稱為數據庫的不一致性。這種不一致性是由甲、乙兩個售票員并發操作引起的。在并發操作情況下,對甲、乙兩個事務操作序列的調度是隨機的。若按上面的調度序列行,甲事務的修改就被丟失。這是由于第4步中乙事務修改A并寫回覆蓋了甲事務的修改。 |
| 并發操作帶來的數據庫不一致性可以分為四類:丟失或覆蓋更新、臟讀、不可重復讀和幻像讀,上例只是并發問題的一種。 |
| (1)丟失或覆蓋更新(lost update) |
| 當兩個或多個事務選擇同一數據,并且基于最初選定的值更新該數據時,會發生丟失更新問題。每個事務都不知道其它事務的存在。最后的更新將重寫由其它事務所做的更新,這將導致數據丟失。上面預定飛機票的例子就屬于這種并發問題。事務1與事務2先后讀入同一數據A=16,事務1執行A-1,并將結果A=15寫回,事務2執行A-1,并將結果A=15寫回。事務2提交的結果覆蓋了事務1對數據庫的修改,從而使事務1對數據庫的修改丟失了。 |
| (2)臟讀 |
| 一個事務讀取了另一個未提交的并行事務寫的數據。當第二個事務選擇其它事務正在更新的行時,會發生未確認的相關性問題。第二個事務正在讀取的數據還沒有確認并且可能由更新此行的事務所更改。換句話說,當事務1修改某一數據,并將其寫回磁盤,事務2讀取同一數據后,事務1由于某種原因被撤銷,這時事務1已修改過的數據恢復原值,事務2讀到的數據就與數據庫中的數據不一致,是不正確的數據,稱為臟讀。 |
| 例如,在下圖中,事務1將C值修改為200,事務2讀到C為200,而事務1由于某種原因撤銷,其修改作廢,C恢復原值100,這時事務2讀到的就是不正確的“臟“數據了。 |
| (3)不可重復讀(nonrepeatable read) |
| 一個事務重新讀取前面讀取過的數據,發現該數據已經被另一個已提交的事務修改過。即事務1讀取某一數據后,事務2對其做了修改,當事務1再次讀數據時,得到的與第一次不同的值。 |
| 例如,在下圖中,事務1讀取B=100進行運算,事務2讀取同一數據B,對其進行修改后將B=200寫回數據庫。事務1為了對讀取值校對重讀B,B已為200,與第一次讀取值不一致。 |
| (4)幻像讀 |
| 如果一個事務在提交查詢結果之前,另一個事務可以更改該結果,就會發生這種情況。這句話也可以這樣解釋,事務1按一定條件從數據庫中讀取某些數據記錄后未提交查詢結果,事務2刪除了其中部分記錄,事務1再次按相同條件讀取數據時,發現某些記錄神秘地消失了;或者事務1按一定條件從數據庫中讀取某些數據記錄后未提交查詢結果,事務2插入了一些記錄,當事務1再次按相同條件讀取數據時,發現多了一些記錄。 |
| 產生上述四類數據不一致性的主要原因是并發操作破壞了事務的隔離性。并發控制就是要用正確的方式調度并發操作,使一個用戶事務的執行不受其他事務的干擾,從而避免造成數據的不一致性。 |
| 3、并發場景列舉 |
| 結合SQL語句,列舉各種并發情況(包括可能導致數據不一致性和對數據一致性不產生影響的情況)。A表示某一條數據,b和c都表示滿足某一個標準的兩條或多條數據,^表示“非”的意思,∈表示屬于或包含于的意思,1表示第一個事務,2表示第二個事務。 |
| (二)并發操作的調度 |
| 計算機系統對并行事務中并行操作的調度是隨機的,而不同的調度可能會產生不同的結果,那么哪個結果是正確的,哪個是不正確的呢? |
| 如果一個事務運行過程中沒有其他事務在同時運行,也就是說沒有受到其他事務的干擾,那么就可能認為該事務的運行結果是正常的或者預想的,因此將所有事務串行起來的調度策略是正確的調度策略。雖然以不同的順序串行執行事務也可能會產生不同的結果,但由于不會將數據庫置于不一致狀態,所以都可以認為是正確的。由此可以得到如下結論:幾個事務的并行執行是正確的,當且僅當其結果與按某一次序串行地執行它們的結果相同。我們稱這種并行調度策略為可串行化(serializable)的調度。可串行性(serializability)是并行事務正確性的唯一準則。 |
| 例如,現在有兩個事務,分別包含下列操作: |
| 事務1:讀B;A=B+1;寫回A; |
| 事務2:讀A;B=A+1;寫回B; |
| 假設A的初值為10,B的初值為2。下圖給出了對這兩個事務的三種不同的調度策略,(a)和(b)為兩種不同的串行調度策略,雖然執行結果不同,但他們都是正確的調度。(c)中兩個事務是交錯執行的,由于執行結果與(a)、(b)的結果都不同,所以是錯誤的調度。(d)中的兩個事務也是交錯執行的,由于執行結果與串行調度1(圖(a))的執行結果相同,所以是正確的調度。 |
| 為了保證并行操作的正確性,DBMS的并行控制機制必須提供一定的手段來保證調度是可串行化的。 |
| 從理論上講,在某一事務執行時禁止其他事務執行的調度策略一定是可串行化的調度,這也是最簡單的調度策略,但這種方法實際上是不可行的,因為它使用戶不能充分共享數據庫資源。 |
| 目前DBMS普遍采用封鎖方法(悲觀方法,DM采用的就是這種方法,SQL Server也是采用的這種方法)來保證調度的正確性;即保證并行操作調度的可串行性。除此之外還有其他一些方法,如時標方法、樂觀方法等。 |
| ●悲觀并發控制 |
| 鎖定系統阻止用戶以影響其它用戶的方式修改數據。如果用戶執行的操作導致應用了某個鎖,則直到這個鎖的所有者釋放該鎖,其它用戶才能執行與該鎖沖突的操作。該方法主要用在數據爭奪激烈的環境中,以及出現并發沖突時用鎖保護數據的成本比回滾事務的成本低的環境中,因此稱該方法為悲觀并發控制。 |
| ●樂觀并發控制 |
| 在樂觀并發控制中,用戶讀數據時不鎖定數據。在執行更新時,系統進行檢查,查看另一個用戶讀過數據后是否更改了數據。如果另一個用戶更新了數據,將產生一個錯誤。一般情況下,接收錯誤信息的用戶將回滾事務并重新開始。該方法主要用在數據爭奪少的環境內,以及偶爾回滾事務的成本超過讀數據時鎖定數據的成本的環境內,因此稱該方法為樂觀并發控制。 |
| ●時標并發控制 |
| 時標和封鎖技術之間的基本區別是封鎖是使一組事務的并發執行(即交叉執行)同步,使用它等價于這些事務的某一串行操作;時標法也是使用一組事務的交叉執行同步,但是使它等價于這些事務的一個特定的串行執行,即由時標的時序所確定的一個執行。如果發生沖突,是通過撤銷并重新啟動一個事務解決的。事務重新啟動,則賦予新的時標。 |
| 在2級封鎖協議中,由于讀完數據后即可釋放S鎖,所以它不能保證可重復讀。 |
| 3級封鎖協議 |
| 3級封鎖協議的內容是:1級封鎖協議加上事務T在讀取數據之前必須先對其加S鎖,直到事務結束才釋放。 |
| 3級封鎖協議除防止丟失或覆蓋更新和不臟讀數據外,還進一步防止了不可重復讀和幻想讀。例如下圖,使用3級封鎖協議解決了不可重復讀和幻像讀問題。 |
| 上圖中,事務1在讀A,B之前,先對A,B加S鎖,這樣其他事務只能再對A,B加S鎖,而不能加X鎖,即其他事務只能讀A,B,而不能修改它們。所以當事務2為修改B而申請對B的X鎖時被拒絕,使其他無法執行修改操作,只能等待事務1釋放B上的鎖。接著事務1為驗算再讀A,B,這時讀出的B仍是100,求和結果仍為150,即可重復讀。 |
| 上述三級協議的主要區別在于什么操作需要申請封鎖以及何時釋放鎖(即持鎖時間)。三級封鎖協議可以總結為下表。 |
| (6)保證并行調度可串行性的封鎖協議――兩段封鎖協議 |
| 可串行性是并行調度正確性的唯一準則,兩段鎖(two-phase locking,簡稱2PL)協議是為保證并行調度可串行性而提供的封鎖協議。 |
| 兩段封鎖協議規定: |
| ①在對任何數據進行讀、寫操作之前,事務首先要獲得對該數據的封鎖,而且②在釋放一個封鎖之后,事務不再獲得任何其他封鎖。 |
| 所謂“兩段”鎖的含義是,事務分為兩個階段,第一階段是獲得封鎖,也稱為擴展階段,第二階段是釋放封鎖,也稱為收縮階段。 |
| 例如,事務1的封鎖序列是: |
| Slock A... Slock B… Xlock C… Unlock B… Unlock A… Unlock C; |
| 事務2的封鎖序列是: |
| Slock A... Unlock A… Slock B… Xlock C… Unlock C… Unlock B; |
| 則事務1遵守兩段封鎖協議,而事務2不遵守兩段封鎖協議。 |
| 可以證明,若并行執行的所有事務均遵守兩段鎖協議,則對這些事務的所有并行調度策略都是可串行化的。因此我們得出如下結論:所有遵守兩段鎖協議的事務,其并行的結果一定是正確的。 |
| 需要說明的是,事務遵守兩段鎖協議是可串行化調度的充分條件,而不是必要條件。即可串行化的調度中,不一定所有事務都必須符合兩段封鎖協議。例如,在下圖中,(a)和(b)都是可串行化的調度,但(a)遵守兩段鎖協議,(b)不遵守兩段鎖協議。 |
| 死鎖問題在操作系統和一般并行處理中已做了深入研究,但數據庫系統有其自己的特點,操作系統中解決死鎖的方法并不一定合適數據庫系統。 |
| 目前在數據庫中解決死鎖問題主要有兩類方法,一類方法是采取一定措施來預防死鎖的發生,另一類方法是允許發生死鎖,采用一定手段定期診斷系統中有無死鎖,若有則解除之。 |
| 1死鎖的預防 |
| 在數據庫系統中,產生死鎖的原因是兩個或多個事務都已封鎖了一些數據對象,然后又都請求對已為其他事務封鎖的數據對象加鎖,從而出現死鎖等待。防止死鎖的發生其實就是要破壞產生死鎖的條件。預防死鎖通常有兩種方法。 |
| ●一次封鎖法 |
| 一次封鎖法要求每個事務必須一次將所有要使用的數據全部加鎖,否則就不能繼續執行。例如,在上圖的例子中,如果事務T1將數據對象A和B一次加鎖,T1就可以執行下去,而T2等待。T1執行完后釋放A,B上的鎖,T2繼續執行。這樣就不會發生死鎖。 |
| 一次封鎖法雖然可以有效地防止死鎖的發生,但也存在問題。第一,一次就將以后要用到的全部數據加鎖,勢必擴大了封鎖的范圍,從而降低了系統的并發度。第二,數據庫中數據是不斷變化的,原來不要求封鎖的數據,在執行過程中可能會變成封鎖對象,所以很難實現精確地確定每個事務所要封鎖的數據對象,只能采取擴大封鎖范圍,將事務在執行過程中可能要封鎖的數據對象全部加鎖,這就進一步降低了并發度。 |
| ●順序封鎖法 |
| 順序封鎖法是預先對數據對象規定一個封鎖順序,所有事務都按這個順序執行封鎖。在上例中,我們規定封鎖順是A,B,T1和T2都按此順序封鎖,即T2也必須先封鎖A。當T2請求A的封鎖時,由于T1已經封鎖住A,T2就只能等待。T1釋放A,B上的鎖后,T2繼續運行。這樣就不會發生死鎖。 |
| 順序封鎖法同樣可以有效地防止死鎖,但也同樣存在問題。第一,數據庫系統中可封鎖的數據對象及其眾多,并且隨數據的插入、刪除等操作而不斷地變化,要維護這樣極多而且變化的資源的封鎖順序非常困難,成本很高。第二,事務的封鎖請求可以隨著事務的執行而動態地決定,很難事先確定每一個事務要封鎖哪些對象,因此也就很難按規定的順序取施加封鎖。例如,規定數據對象的封鎖順序為A,B,C,D,E。事務T3起初要求封鎖數據對象B,C,E,但當它封鎖B,C后,才發現還需要封鎖A,這樣就破壞了封鎖順序。 |
| 可見,在操作系統中廣為采用的預防死鎖的策略并不很適合數據庫的特點,因此DBMS在解決死鎖的問題上更普遍采用的是診斷并解除死鎖的方法。 |
| 2、死鎖的診斷與解除 |
| 數據庫系統中診斷死鎖的方法與操作系統類似,即使用一個事務等待圖,它動態地反映所有事務的等待狀況。并發控制子系統周期性地(比如每隔1分鐘)檢測事務等待圖,如果發現圖中存在回路,則表示系統中出現了死鎖。關于診斷死鎖的詳細討論請參閱操作系統的有關書籍。 |
| DBMS的并發控制子系統一旦檢測到系統中存在死鎖,就要設法解除。通常采用的方法是選擇一個處理死鎖代價最小的事務,將其撤銷,釋放此事務持有的所有的鎖,使其他事務能繼續運行下去。 |
| 二、DM的并發控制 |
| (一)事務隔離級 |
| 事務的隔離級描述了給定事務的行為對其它并發執行事務的暴露程度。 SQL-92共規定了四種隔離級別,通過選擇四個隔離級中的一個,用戶能增加對其它未提交事務的暴露程度,獲得更高的并發度。隔離級別是一個事務必須與其它事務進行隔離的程度。 |
| SQL-92的四種隔離級別如下所示,DM支持所有這些隔離級別: |
| (1)臟讀(READ UNCOMMITTED):事務隔離的最低級別,事務可能查詢到其它事務未提交的數據, 僅可保證不讀取物理損壞的數據)。 |
| (2)讀提交(READ COMMITTED):DM默認級別,保證不讀臟數據。 |
| (3)可重復讀(REPEATABLE READ):保證不可重復讀,但有可能讀入幻像數據。 |
| (4)可串行化(SERIALIZABLE):事務隔離的最高級別,事務之間完全隔離。 |
| DM允許用戶改變未啟動的事務的隔離級和讀寫特性 ,而且設置的選項將一直對那個連接保持有效,直到顯式更改該選項為止。設置事務隔離級別雖然使程序員承擔了某些完整性問題所帶來的風險,但可以換取對數據更大的并發訪問權。與以前的隔離級別相比,每個隔離級別都提供了更大的隔離性,但這是通過在更長的時間內占用更多限制鎖換來的。DM還提供設置事務只讀屬性的語句,使用該語句后該事務只能做查詢操作,不能更新數據庫。 |
| 需要注意的是,事務的隔離級別并不影響事務查看本身對數據的修改,也就是說,事務總可以查看自己對數據的修改。事務的隔離級別需要根據實際需要設定,較低的隔離級別可以增加并發,但代價是降低數據的正確性。相反,較高的隔離級別可以確保數據的正確性,但可能對并發產生負面影響。應用程序要求的隔離級別確定了DM使用的鎖定行為。 |
| 下表中列出四種隔離級別允許不同類型的現象 |
| 注意:丟失或覆蓋更新在所有的標準SQL隔離級中都是禁止的 |
| (二)并發處理 |
| 1、數據鎖定機制 |
| DM用數據鎖定機制來解決并發問題。它可以保證任何時候都可以有多個正在運行的事務,但是所有事務都在彼此完全隔離的環境中運行。 |
| DM的封鎖對象為表和元組。封鎖的實施有自動和手動兩種,即隱式上鎖和顯式上鎖。隱式封鎖動作的封鎖根據事務的隔離級有所不同。同時, DM提供給用戶4種手動上鎖語句,用以適應用戶定義的應用系統。 |
| 一般而言, DM的隱式封鎖足以保證數據的一致性,但用戶可以根據自己的需要改變對表的封鎖。 DM提供給用戶四種表鎖:意向共享鎖(IS:INTENSIVE SHARE)、共享鎖(S:SHARE)、意向排它鎖(IX:INTENSIVE EXCLUSIVE)和排它鎖(X:EXCLUSIVE)。例如,在讀提交隔離級下,系統缺省的表鎖是 IS或IX ,在這兩種表鎖下,在訪問元組前還需對元組進行封鎖,為了提高系統的效率,用戶可以手動對表進行 X封鎖,這樣,就不需對訪問元組封鎖。 |
| 封鎖機制要達到以下目的: |
| (1)一致性:保證用戶正在查看時,改變的數據并未從根本上發生變化。 |
| (2)完整性:保證數據庫的基本結構以正確的順序,準確地反映對它們的所有改變。 |
| 一個“ 鎖定” 可以認為是當某一進程需要防止其它進程做某事時獲得的某種東西,當該進程不再關心此事時就 “釋放 ”此鎖定,通常一個鎖定是加在某個 “資源 ”(某些客體,如表 )上的。 |
| DM的內部鎖定是自動完成的。當某一進程要查看一個客體但不允許其他人修改它時,就獲得一個共享方式的鎖定。當某一進程要修改一客體,并且防止任何其它進程修改它時,就獲得更新方式的鎖定。當某一進程要修改一客體,并且防止任何其它進程修改它或以共享方式封鎖它時,就獲得獨占方式的鎖定。 |
| 2、鎖定類型 |
| DM中的鎖有三種,表鎖、行鎖和鍵范圍鎖。 |
| ●表鎖 |
| 表鎖用來封鎖表對象,在對表進行檢索和更新時,DM會對表對象進行封鎖,但是DM為用戶提供手動的表鎖語句,用戶可以根據自己的需要改變對表的封鎖類型。表鎖的模式:意向共享鎖 IS,意向排它鎖 IX,共享鎖 S,排它鎖 X,共四種,其相容矩陣可定義如下表。 |
| ●行鎖 |
| 行鎖封鎖元組,在存取元組和更新元組前, DM會對元組上行鎖,系統不提供手動的行封鎖語句。行鎖有兩種模式:共享鎖(S)、排它鎖(X),其相容矩陣定義如下表。 |
| ●鍵范圍鎖 |
| 鍵范圍鎖用在可串行事務上,主要解決了幻像讀并發問題。鍵范圍鎖覆蓋單個記錄以及記錄之間的范圍,可以防止對事務訪問的記錄集進行幻像插入或刪除。鍵范圍鎖僅用于在可串行隔離級別上操作的事務。 |
| 可串行性要求,如果任意一個查詢在一個事務中后面的某一時刻再次執行,其所獲取的行集應與該查詢在同一事務中以前執行時所獲得的行集相同。如果本查詢試圖提取的行不存在,則在試圖訪問該行的事務完成之前,其它事務不能插入該行。如果允許另一個事務插入該行,則它將以幻像出現。 |
| 如果另一個事務試圖插入駐留在鎖定數據頁上的行,頁級鎖定可以防止添加幻像行,并維護可串行性。但是,如果該行要添加到未被第一個事務鎖定的數據頁,應設定鎖定機制防止添加該行。 |
| 鍵范圍鎖通過覆蓋索引行和索引行之間的范圍來工作(而不是鎖定整個基礎表的行)。因為第二個事務在該范圍內進行任何行插入、更新或刪除操作時均需要修改索引,而鍵范圍鎖覆蓋了索引項,所以在第一個事務完成之前會阻塞第二個事務的進行。 |
| 鍵范圍鎖由系統自行執行,執行的條件是: (1) 事務隔離級為可串行化級; (2) 查詢結果通過某個索引得出。 |
| 用戶上鎖成功后鎖將一直有效,直到當前事務結束時,該鎖被系統自動解除。 |
| 3、鎖定類型比較 |
| 4、SQL語句鎖定分析 |
| DM對各種 DDL和GRANT 等非DML 語句都分解為增、刪、改。下表為DM對各種DML語句和查詢語句的封鎖策略。 |
| 注:S* 表示瞬時鎖,在語句結束后釋放;Range表示鍵范圍鎖。 |
| 上表只是系統在一般情況下的處理,當系統檢測到有鎖升級的可能,則會升級鎖。一般而言,IS鎖升級為 S鎖,IX鎖升級為 X鎖,同時,不再進行行封鎖。 |
| 5、自定義鎖定提高系統效率 |
| DM也提供了兩個函數 SET_TABLE_OPTION([db.][sch.]tablename, option, value) 、SET_INDEX_OPTION([db.]indexname, option, value)(具體語法參見《 DM_SQL語言使用手冊》第 8 章)供用戶自行定義鎖定類型,以增強系統并發度,提高系統效率。這兩個函數是為那些清楚地知道特定類型的鎖適用于何種情況的專家級用戶提供的。 |
| 函數SET_TABLE_OPTION() 用于禁用指定表上的頁級鎖、行級鎖或同時禁用二者,這一設置對該表上的所有索引都生效。函數 SET_INDEX_OPTION() 則用于禁用某一索引上的頁級鎖、行級鎖或同時禁用二者。 |
| 例如,當用戶只需要修改索引中某定長字段時,修改操作不會造成 B 樹的分裂與合并,此時就可以禁用該索引的頁級鎖。又如,當所有的用戶都只做插入操作時,用戶之間并不會對同一元組進行操作,此時就可以禁用行級鎖。當用戶能保證不對表進行增、刪、改,而只是進行查詢時,則可以同時禁用該表上的頁級鎖和行級鎖,此時并發度最高。 |
| 6、死鎖處理 |
| 解決死鎖問題的三種方法:預防死鎖、檢測死鎖及避免死鎖。死鎖預防要求用戶進程事先申報所需的資源或按嚴格的規程申請資源,而死鎖檢測原則上應允許死鎖發生,在適當的時機檢查,若發生死鎖,則設法排除之。與預防死鎖相比,后者過于放手,致使死鎖頻繁。而避免死鎖則以事務撤消為前提,當不能獲得資源批準時,立刻進行死鎖檢測。它既不象預防死鎖那樣過于保守,也不象死鎖檢測那樣過于放開,由于檢測及時,由歸納法可知,在已獲準等待的事務中,不可能存在死鎖,所以檢測算法比較簡單。 |
| DM4系統采用的是避免死鎖方法。每當一個事務所申請占有的資源不能被立即獲得時,便進行死鎖檢測,不存在死鎖,則該事務入等待隊列。否則,DM4視為產生運行時錯誤,將當前語句回滾。采用這種機制,從用戶的角度看,DM4不存在解鎖問題。 |
| 7、加索引和不加索引的封鎖區別 |
| 加索引和不加索引的情況下,DM的封鎖機制會影響到實際的封鎖范圍。索引的作用就在于,可以在查詢中減少對無關數據的掃描。而在一般的隔離級中,總是要對掃描到的數據進行封鎖。所以,利用索引可以減少封鎖的數量,沖突的可能性也會大大減少。 |
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
- 上一篇: 我是游泳高手
- 下一篇: 如何把文件模版上传到SAP数据库层.