瘋狂

          STANDING ON THE SHOULDERS OF GIANTS
          posts - 481, comments - 486, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          事務(wù)和兩階段提交

          Posted on 2011-10-09 14:41 瘋狂 閱讀(13223) 評論(0)  編輯  收藏 所屬分類: database

           

        1. 1 事務(wù)的ACID

        2. 事務(wù)是保證數(shù)據(jù)庫從一個一致性的狀態(tài)永久地變成另外一個一致性狀態(tài)的根本,其中,ACID是事務(wù)的基本特性。

          A是Atomicity,原子性。一個事務(wù)往往涉及到許多的子操作,原子性則保證這些子操作要么都做,要么都不做,而不至于出現(xiàn)事務(wù)的部分操作成功,而另外一部分操作沒有成功。如果事務(wù)在執(zhí)行的過程中發(fā)生錯誤,那么數(shù)據(jù)庫將回滾到事務(wù)發(fā)生之前的狀態(tài)。比如銀行的轉(zhuǎn)賬服務(wù),這個事務(wù)的最終結(jié)果一定是:某個賬戶的余額增加了x,而另外一個賬戶的余額減少了x,或者兩個賬戶的余額未發(fā)生變化。而不會出現(xiàn)其他情況。

          C是Consistency,一致性。一致性是指事務(wù)發(fā)生前和發(fā)生以后,都不會破壞數(shù)據(jù)庫的約束關(guān)系,保證了數(shù)據(jù)庫元素的正確性、有效性和完整性。這種約束關(guān)系可以是數(shù)據(jù)庫內(nèi)部的約束,比如數(shù)據(jù)庫元素的值必須在一定的范圍內(nèi),也可以是應(yīng)用帶來的約束,比如轉(zhuǎn)賬以后銀行賬戶的余額不能為負數(shù)。

          I是Isolation,隔離性。一個事務(wù)的操作在未提交以前,是不會被并行發(fā)生的其他事務(wù)訪問到的。也就是說,數(shù)據(jù)庫操作不會看到某個事務(wù)的中間操作結(jié)果,比如轉(zhuǎn)賬過程中,用戶是不能查詢到一個賬戶余額減少了,而另外一個賬戶余額未發(fā)生變化的情況。

          D是Durability,持久性。事務(wù)完成以后,它對數(shù)據(jù)庫的影響是永久性的,即使在數(shù)據(jù)庫系統(tǒng)發(fā)生宕機或者其他故障的情況下,這種影響也會得到保持。

          • 2 兩階段提交

          在分布式系統(tǒng)中,事務(wù)往往包含有多個參與者的活動,單個參與者上的活動是能夠保證原子性的,而多個參與者之間原子性的保證則需要通過兩階段提交來實現(xiàn),兩階段提交是分布式事務(wù)實現(xiàn)的關(guān)鍵。

          很明顯,兩階段提交保證了分布式事務(wù)的原子性,這些子事務(wù)要么都做,要么都不做。而數(shù)據(jù)庫的一致性是由數(shù)據(jù)庫的完整性約束實現(xiàn)的,持久性則是通過commit日志來實現(xiàn)的,不是由兩階段提交來保證的。至于兩階段提交如何保證隔離性,可以參考Large-scale Incremental Processing Using Distributed Transactions and Notifications中兩階段提交的具體實現(xiàn)。

          兩階段提交的過程涉及到協(xié)調(diào)者和參與者。協(xié)調(diào)者可以看做成事務(wù)的發(fā)起者,同時也是事務(wù)的一個參與者。對于一個分布式事務(wù)來說,一個事務(wù)是涉及到多個參與者的。具體的兩階段提交的過程如下:

          第一階段:

          首先,協(xié)調(diào)者在自身節(jié)點的日志中寫入一條的日志記錄,然后所有參與者發(fā)送消息prepare T,詢問這些參與者(包括自身),是否能夠提交這個事務(wù);

          參與者在接受到這個prepare T 消息以后,會根據(jù)自身的情況,進行事務(wù)的預(yù)處理,如果參與者能夠提交該事務(wù),則會將日志寫入磁盤,并返回給協(xié)調(diào)者一個ready T信息,同時自身進入預(yù)提交狀態(tài)狀態(tài);如果不能提交該事務(wù),則記錄日志,并返回一個not commit T信息給協(xié)調(diào)者,同時撤銷在自身上所做的數(shù)據(jù)庫改;

          參與者能夠推遲發(fā)送響應(yīng)的時間,但最終還是需要發(fā)送的。

          第二階段:

          協(xié)調(diào)者會收集所有參與者的意見,如果收到參與者發(fā)來的not commit T信息,則標識著該事務(wù)不能提交,協(xié)調(diào)者會將Abort T 記錄到日志中,并向所有參與者發(fā)送一個Abort T 信息,讓所有參與者撤銷在自身上所有的預(yù)操作;

          如果協(xié)調(diào)者收到所有參與者發(fā)來prepare T信息,那么協(xié)調(diào)者會將Commit T日志寫入磁盤,并向所有參與者發(fā)送一個Commit T信息,提交該事務(wù)。若協(xié)調(diào)者遲遲未收到某個參與者發(fā)來的信息,則認為該參與者發(fā)送了一個VOTE_ABORT信息,從而取消該事務(wù)的執(zhí)行。

          參與者接收到協(xié)調(diào)者發(fā)來的Abort T信息以后,參與者會終止提交,并將Abort T 記錄到日志中;如果參與者收到的是Commit T信息,則會將事務(wù)進行提交,并寫入記錄

          一般情況下,兩階段提交機制都能較好的運行,當在事務(wù)進行過程中,有參與者宕機時,他重啟以后,可以通過詢問其他參與者或者協(xié)調(diào)者,從而知道這個事務(wù)到底提交了沒有。當然,這一切的前提都是各個參與者在進行每一步操作時,都會事先寫入日志。

          唯一一個兩階段提交不能解決的困境是:當協(xié)調(diào)者在發(fā)出commit T消息后宕機了,而唯一收到這條命令的一個參與者也宕機了,這個時候這個事務(wù)就處于一個未知的狀態(tài),沒有人知道這個事務(wù)到底是提交了還是未提交,從而需要數(shù)據(jù)庫管理員的介入,防止數(shù)據(jù)庫進入一個不一致的狀態(tài)。當然,如果有一個前提是:所有節(jié)點或者網(wǎng)絡(luò)的異常最終都會恢復(fù),那么這個問題就不存在了,協(xié)調(diào)者和參與者最終會重啟,其他節(jié)點也最終也會收到commit T的信息。

          • 3 日志

          數(shù)據(jù)庫日志保證了事務(wù)執(zhí)行的原子性和持久性,日志類型可以分為redo log,undo log,undo/redo log。關(guān)于這幾種日志形式的具體介紹,可以參照:

          http://nosql-wiki.org/foswiki/bin/view/Main/TransactonLog
          轉(zhuǎn)載自:http://rdc.taobao.com/blog/cs/?p=1183

          主站蜘蛛池模板: 宜城市| 凌源市| 福鼎市| 霸州市| 扎兰屯市| 连南| 拜城县| 甘德县| 如皋市| 德昌县| 饶阳县| 湖北省| 太白县| 扶余县| 社旗县| 綦江县| 尉犁县| 图片| 巴里| 巴彦县| 丽水市| 曲沃县| 邳州市| 鄂伦春自治旗| 潮安县| 宣城市| 淮北市| 密云县| 温泉县| 双桥区| 溧阳市| 长武县| 福鼎市| 德格县| 射阳县| 醴陵市| 阳城县| 滨州市| 洪雅县| 平罗县| 墨江|