導航:首頁 > 編程大全 > 資料庫事物實現原理

資料庫事物實現原理

發布時間:2025-07-13 11:49:05

資料庫事務原子性,一致性是怎樣實現的

這個問題的有趣之處,不在於問題本身(「原子性、一致性的實現機制是什麼」),而在於回答者的分歧反映出來的另外一個問題:原子性和一致性之間的關系是什麼?

我特別關注了@我練功發自真心
的答案,他正確地指出了,為了保證事務操作的原子性,必須實現基於日誌的REDO/UNDO機制。但這個答案仍然是不完整的,因為原子性並不能夠完全保證一致性。

按照我個人的理解,在事務處理的ACID屬性中,一致性是最基本的屬性,其它的三個屬性都為了保證一致性而存在的。

首先回顧一下一致性的定義。所謂一致性,指的是數據處於一種有意義的狀態,這種狀態是語義上的而不是語法上的。最常見的例子是轉帳。例如從帳戶A轉一筆錢到帳戶B上,如果帳戶A上的錢減少了,而帳戶B上的錢卻沒有增加,那麼我們認為此時數據處於不一致的狀態。


資料庫實現的場景中,一致性可以分為資料庫外部的一致性和資料庫內部的一致性。前者由外部應用的編碼來保證,即某個應用在執行轉帳的資料庫操作時,必須在
同一個事務內部調用對帳戶A和帳戶B的操作。如果在這個層次出現錯誤,這不是資料庫本身能夠解決的,也不屬於我們需要討論的范圍。後者由資料庫來保證,即
在同一個事務內部的一組操作必須全部執行成功(或者全部失敗)。這就是事務處理的原子性。

為了實現原子性,需要通過日誌:將所有對
數據的更新操作都寫入日誌,如果一個事務中的一部分操作已經成功,但以後的操作,由於斷電/系統崩潰/其它的軟硬體錯誤而無法繼續,則通過回溯日誌,將已
經執行成功的操作撤銷,從而達到「全部操作失敗」的目的。最常見的場景是,資料庫系統崩潰後重啟,此時資料庫處於不一致的狀態,必須先執行一個crash
recovery的過程:讀取日誌進行REDO(重演將所有已經執行成功但尚未寫入到磁碟的操作,保證持久性),再對所有到崩潰時尚未成功提交的事務進行
UNDO(撤銷所有執行了一部分但尚未提交的操作,保證原子性)。crash
recovery結束後,資料庫恢復到一致性狀態,可以繼續被使用。

日誌的管理和重演是資料庫實現中最復雜的部分之一。如果涉及到並行處理和分布式系統(日誌的復制和重演是資料庫高可用性的基礎),會比上述場景還要復雜得多。

但是,原子性並不能完全保證一致性。在多個事務並行進行的情況下,即使保證了每一個事務的原子性,仍然可能導致數據不一致的結果。例如,事務1需要將100元轉入帳號A:先讀取帳號A的值,然後在這個值上加上100。但是,在這兩個操作之間,另一個事務2修改了帳號A的值,為它增加了100元。那麼最後的結果應該是A增加了200元。但事實上,
事務1最終完成後,帳號A只增加了100元,因為事務2的修改結果被事務1覆蓋掉了。

為了保證並發情況下的一致性,引入了隔離性,即保證每一個事務能夠看到的數據總是一致的,就好象其它並發事務並不存在一樣。用術語來說,就是多個事務並發執行後的狀態,和它們串列執行後的狀態是等價的。怎樣實現隔離性,已經有很多人回答過了,原則上無非是兩種類型的鎖:


種是悲觀鎖,即當前事務將所有涉及操作的對象加鎖,操作完成後釋放給其它對象使用。為了盡可能提高性能,發明了各種粒度(資料庫級/表級/行級……)/各
種性質(共享鎖/排他鎖/共享意向鎖/排他意向鎖/共享排他意向鎖……)的鎖。為了解決死鎖問題,又發明了兩階段鎖協議/死鎖檢測等一系列的技術。

一種是樂觀鎖,即不同的事務可以同時看到同一對象(一般是數據行)的不同歷史版本。如果有兩個事務同時修改了同一數據行,那麼在較晚的事務提交時進行沖突
檢測。實現也有兩種,一種是通過日誌UNDO的方式來獲取數據行的歷史版本,一種是簡單地在內存中保存同一數據行的多個歷史版本,通過時間戳來區分。

鎖也是資料庫實現中最復雜的部分之一。同樣,如果涉及到分布式系統(分布式鎖和兩階段提交是分布式事務的基礎),會比上述場景還要復雜得多。

@
我練功發自真心
提到,其他回答者說的其實是操作系統對atomic的理解,即並發控制。我不能完全同意這一點。資料庫有自己的並發控制和鎖問題,雖然在原理上和操作系統
中的概念非常類似,但是並不是同一個層次上的東西。資料庫中的鎖,在粒度/類型/實現方式上和操作系統中的鎖都完全不同。操作系統中的鎖,在資料庫實現中
稱為latch(一般譯為閂)。其他回答者回答的其實是「在並行事務處理的情況下怎樣保證數據的一致性」。

最後回到原來的問題(「原子性、一致性的實現機制是什麼」)。我手頭有本Database
System
Concepts(4ed,有點老了),在第15章的開頭簡明地介紹了ACID的概念及其關系。如果你想從概念上了解其實現,把這本書的相關章節讀完應該能大概明白。如果你想從實踐上了解其實現,可以找innodb這樣的開源引擎的源代碼來讀。不過,即使是一個非常粗糙的開源實現(不考慮太復雜的並行處理,不考慮分布式系統,不考慮針對操作系統和硬體的優化之類),要基本搞明白恐怕也不是一兩年的事。

閱讀全文

與資料庫事物實現原理相關的資料

熱點內容
文件夾到u盤變成多少kb 瀏覽:351
sfs文件怎麼解壓 瀏覽:39
為什麼app隱私政策總是變更 瀏覽:490
ai文件轉換器軟體 瀏覽:217
判斷java數組裡面的個數 瀏覽:214
老版本三國殺10 瀏覽:949
為什麼有些人不能學習編程 瀏覽:955
火山編程和易安卓哪個好學 瀏覽:695
java代理ip工具類 瀏覽:171
全選多個文件名復制路徑不顯示呢 瀏覽:957
蘋果粉色app都有什麼 瀏覽:378
小牛app怎麼樣 瀏覽:972
mxd文件打開無內容 瀏覽:130
手機cnt文件能刪除嗎 瀏覽:391
游戲局內文件名 瀏覽:956
apk編輯器不顯示文件 瀏覽:277
app是什麼產品 瀏覽:813
ps打開文件不見文件 瀏覽:82
linux定時讀取數據生成文件 瀏覽:420
微信視頻文件已被清理 瀏覽:716

友情鏈接