本文探讨南大通用GBase 8s資料庫的事務處理特性,揭示其如何確定ACID特性,并有效管理并發事務。
事務的概念及ACID特性
事務(Transaction)
将使用者在資料庫中的某些操作集合看作一個整體,在其有序執行的過程中不被其他操作影響,這樣的操作集合就是事務。
事務(Transaction)是對資料庫進行操作的集合。該集合是一個不可分割的具有邏輯功能的工作單元,集合中的操作在事務的一次執行中必須全部被執行或者全部。
事務的特性(ACID 特性)
- Atomicity: 原子性
構成該事務的操作集合中的全部操作在事務的運作過程中全部執行或者全部不執行。
- Consistency: 一緻性
事務運作的結果應該使資料庫保持資料一緻性。
- Isolation:隔離性
構成某個事務的全部操作與其他事務或操作是隔離的,同時執行的事務之間不能夠互相影響,一個事務單獨運作的結果應該與該事務和其他多個事務同時運作的結果一緻。
- Durability: 持久性
事務的持久性是指事務運作完畢并成功送出後,其對資料庫全部操作的結果應該永久地保留在資料庫中。
并發事務的排程
1、并發問題和并發操作
實際應用中,通常會有來自不同使用者的多個事務并發執行,事務之間會有交叉,這個問題就是事務的并發問題。
并發事務之間互相影響,會破壞相關事務的正常運作,無法保證事務的 ACID 特性,産生資料錯誤。
并發操作(Simultaneous Concurrency)是并發事務中包含的對資料庫的操作,由多個事務并發進行而産生,其最大問題是容易導緻資料庫的不一緻性
舉例說明
兩個售票點同時售出同一天同一車次的車票,第一個售票點執行的資料庫事務 T1 為:
(1)讀出目前車票的剩餘數量 A,假設 A=50;
(2)售出一張票,剩餘數量變為 A=A-1,即 A=49。
第二個售票點執行的資料庫事務 T2 為:
(1)讀出目前車票的剩餘數量 A,假設 A=50;
(2)售出一張票,剩餘數量變為 A=A-1,即 A=49。
事務 T1 和 T2 按照如下順序并發執行:
(1)讀出目前車票的剩餘數量 A,假設 A=50;
(2)讀出目前車票的剩餘數量 A,假設 A=50;
(3)售出一張票,剩餘數量變為 A=A-1,即 A=49;
(4)售出一張票,剩餘數量變為 A=A-1,即 A=49。
事務執行的結果是隻賣了一張車票,而實際上售出了兩張,這樣就可能導緻同一個座位售出兩張車票,資料庫出現了資料的不一緻性錯誤。
并發操作導緻資料庫出現資料不一緻性的問題,如下表所示。事務 T1 将資料對象,即火車票的總數 A 進行了修改,變為 49,而事務 T2 在 T1 修改 A 之前讀取的 A 的值仍然是 50,T2 将此值修改為 49 後寫回資料庫并覆寫了 T1 事務對 A 的修改,此時,A 的值為49,就會出現這種情況:賣出兩張車票後車票總數應為 48,而資料庫中車票的總數為 49,顯然出現了資料的不一緻性錯誤。
2、排程
排程(Schedule)是指事務的執行次序。如果多個事務依次執行,則稱為事務的串行排程(Serial Schedule)。如果多個事務同時執行,則稱為事務的并發排程(Concurrent Schedule)
3、沖突
沖突(conflict):事務排程中的兩個操作(讀操作或寫操作),如果交換順序執行,它們所屬的事務運作結果會改變,那麼這兩個操作就被稱為沖突。
不同僚務對于不同資料對象進行操作(無論是讀操作還是寫操作)不會産生沖突;不同僚務對同一資料對象進行讀操作也不會産生沖突。
4、封鎖
并發控制的主要技術是封鎖(Locking)。封鎖的對象是資料庫中的資料對象,如關系型資料庫中的表、記錄、屬性、索引等。對資料對象加鎖的時機是在事務對其進行操作之前,向系統發出加鎖請求。
加鎖後事務 T就取得了對該資料對象的控制,在事務 T 釋放它的鎖之前,其他事務不能對此資料對象進行任何操作。
封鎖是一種排隊機制,将并行任務按鎖的先後順序排隊,把并行任務變成串行任務。
5、封鎖産生的問題
封鎖技術在一定程度上解決了資料庫的并發事務處理過程中,并發操作給資料庫帶來的資料一緻性問題,但同時産生了新的問題如活鎖和死鎖。
- 活鎖問題
在處理并發事務的過程中,如果事務T1在資料對象R上加鎖,事務T2又請求為資料對象R加鎖,則 T2 必須等待T1釋放加在R上的鎖。如果事務 T3 也請求為 R加鎖,當T1釋放了R上的鎖之後系統首先響應T3的請求,則允許T3對R加鎖,此時 T2 仍需等待T3 釋放加在R上的鎖。然後事務T4又請求封鎖R,當T3釋放了R上的封鎖之後系統 又響應了T4的請求……T2有可能永遠等待而無法為R加鎖,這就是活鎖(Live lock)。
活鎖由于事務永遠得不到封鎖而導緻。避免活鎖可以采用先來先服務的政策。當多個事務請求封鎖同一個資料對象時,可按照請求封鎖的先後次序對事務排隊,資料對象上的鎖一旦釋放就準許申請隊列的第一個事務獲得封鎖。
- 死鎖問題
如果事務 T1 對資料對象 R1 進行封鎖,T2 對資料對象 R2 進行封鎖,然後 T1 又請求對 R2 進行封鎖,由于 T2 已封鎖了 R2,則 T1 必須等待 T2 釋放 R2 上的鎖。接着 T2 又申請對 R1 進行封鎖,由于 T1 已封鎖 R1,是以,T2 也隻能等待 T1 釋放 R1 上的鎖。這樣就出現了事務 T1 等待另一個事務 T2 釋放相關資料對象上的鎖,而 T2 又在等待 T1 釋放相關對象上的鎖,T1 和 T2 兩個事務由于互相等待對方釋放資料對象上的鎖而永遠不能繼續執行,這樣就出現了死鎖。
死鎖(Dead Lock):系統中有兩個或兩個以上的事務都處于等待狀态,并且每個事務都在等待其中另一個事務釋放封鎖,這樣才能繼續執行下去,結果造成任何一個事務都無法繼續執行,這種現象稱資料庫系統進入了“死鎖”(Dead Lock)狀态。
用例簡單複現死鎖産生
GBase模式下(會話1):
那麼兩個會話分别在同一個庫中,對a表和b表加上共享鎖S,當想進行更新時,會話1在等待會話2釋放a的S鎖,而會話2在等待會話1釋放b的S鎖,進而導緻死鎖産生。
那麼在oracle模式下,該用例卻不能産生死鎖。因為在GBase模式下,開啟事務後,可以保證兩個會話在執行更新後才送出保證兩個會話同時進行。
而在oracle模式下,隻能開啟多語句模式,DML語句會自動開啟事務,通過commit/rollback結束事務,DDL會送出事務。進而導緻兩個會話可能無法同時進行,是以并行變成串行,導緻死鎖無法産生。
寫在最後
南大通用GBase 8s資料庫的事務處理能力和并發控制機制,為企業提供了一個可靠、高效和安全的資料處理平台。無論是金融交易還是線上事務處理,GBase 8s都能確定資料的完整性和一緻性,滿足企業對資料庫系統的要求。