Posted on 2011-10-09 14:41
瘋狂 閱讀(13213)
評論(0) 編輯 收藏 所屬分類:
database
1 事務的ACID
事務是保證數據庫從一個一致性的狀態永久地變成另外一個一致性狀態的根本,其中,ACID是事務的基本特性。
A是Atomicity,原子性。一個事務往往涉及到許多的子操作,原子性則保證這些子操作要么都做,要么都不做,而不至于出現事務的部分操作成功,而另外一部分操作沒有成功。如果事務在執行的過程中發生錯誤,那么數據庫將回滾到事務發生之前的狀態。比如銀行的轉賬服務,這個事務的最終結果一定是:某個賬戶的余額增加了x,而另外一個賬戶的余額減少了x,或者兩個賬戶的余額未發生變化。而不會出現其他情況。
C是Consistency,一致性。一致性是指事務發生前和發生以后,都不會破壞數據庫的約束關系,保證了數據庫元素的正確性、有效性和完整性。這種約束關系可以是數據庫內部的約束,比如數據庫元素的值必須在一定的范圍內,也可以是應用帶來的約束,比如轉賬以后銀行賬戶的余額不能為負數。
I是Isolation,隔離性。一個事務的操作在未提交以前,是不會被并行發生的其他事務訪問到的。也就是說,數據庫操作不會看到某個事務的中間操作結果,比如轉賬過程中,用戶是不能查詢到一個賬戶余額減少了,而另外一個賬戶余額未發生變化的情況。
D是Durability,持久性。事務完成以后,它對數據庫的影響是永久性的,即使在數據庫系統發生宕機或者其他故障的情況下,這種影響也會得到保持。
在分布式系統中,事務往往包含有多個參與者的活動,單個參與者上的活動是能夠保證原子性的,而多個參與者之間原子性的保證則需要通過兩階段提交來實現,兩階段提交是分布式事務實現的關鍵。
很明顯,兩階段提交保證了分布式事務的原子性,這些子事務要么都做,要么都不做。而數據庫的一致性是由數據庫的完整性約束實現的,持久性則是通過commit日志來實現的,不是由兩階段提交來保證的。至于兩階段提交如何保證隔離性,可以參考Large-scale Incremental Processing Using Distributed Transactions and Notifications中兩階段提交的具體實現。
兩階段提交的過程涉及到協調者和參與者。協調者可以看做成事務的發起者,同時也是事務的一個參與者。對于一個分布式事務來說,一個事務是涉及到多個參與者的。具體的兩階段提交的過程如下:
第一階段:
首先,協調者在自身節點的日志中寫入一條的日志記錄,然后所有參與者發送消息prepare T,詢問這些參與者(包括自身),是否能夠提交這個事務;
參與者在接受到這個prepare T 消息以后,會根據自身的情況,進行事務的預處理,如果參與者能夠提交該事務,則會將日志寫入磁盤,并返回給協調者一個ready T信息,同時自身進入預提交狀態狀態;如果不能提交該事務,則記錄日志,并返回一個not commit T信息給協調者,同時撤銷在自身上所做的數據庫改;
參與者能夠推遲發送響應的時間,但最終還是需要發送的。
第二階段:
協調者會收集所有參與者的意見,如果收到參與者發來的not commit T信息,則標識著該事務不能提交,協調者會將Abort T 記錄到日志中,并向所有參與者發送一個Abort T 信息,讓所有參與者撤銷在自身上所有的預操作;
如果協調者收到所有參與者發來prepare T信息,那么協調者會將Commit T日志寫入磁盤,并向所有參與者發送一個Commit T信息,提交該事務。若協調者遲遲未收到某個參與者發來的信息,則認為該參與者發送了一個VOTE_ABORT信息,從而取消該事務的執行。
參與者接收到協調者發來的Abort T信息以后,參與者會終止提交,并將Abort T 記錄到日志中;如果參與者收到的是Commit T信息,則會將事務進行提交,并寫入記錄
一般情況下,兩階段提交機制都能較好的運行,當在事務進行過程中,有參與者宕機時,他重啟以后,可以通過詢問其他參與者或者協調者,從而知道這個事務到底提交了沒有。當然,這一切的前提都是各個參與者在進行每一步操作時,都會事先寫入日志。
唯一一個兩階段提交不能解決的困境是:當協調者在發出commit T消息后宕機了,而唯一收到這條命令的一個參與者也宕機了,這個時候這個事務就處于一個未知的狀態,沒有人知道這個事務到底是提交了還是未提交,從而需要數據庫管理員的介入,防止數據庫進入一個不一致的狀態。當然,如果有一個前提是:所有節點或者網絡的異常最終都會恢復,那么這個問題就不存在了,協調者和參與者最終會重啟,其他節點也最終也會收到commit T的信息。
數據庫日志保證了事務執行的原子性和持久性,日志類型可以分為redo log,undo log,undo/redo log。關于這幾種日志形式的具體介紹,可以參照:
http://nosql-wiki.org/foswiki/bin/view/Main/TransactonLog
轉載自:http://rdc.taobao.com/blog/cs/?p=1183