390
技術社區[雲棲]
談談分布式事務之二:基於DTC的分布式事務管理模型[下篇]
[續上篇]當基於LTM或者KTM的事務提升到基於DTC的分布式事務後,DTC成為了本機所有事務型資源管理器的管理者;此外,當一個事務型操作超出了本機的範圍,出現了跨機器的調用後,本機的DTC需要於被調用者所在機器的DTC進行協助。上級對下級(包括本機DTC對本機所有資源管理器,以及上下級DTC)的管理得前提是下級在上級那裏登記,即事務登記(Transaction Enlist)。所有事務參與者,包括所有資源管理器和事務管理器(即DTC)在進行了事務等級完成之後形成了一個樹形的層級結構,該結構的形成是後續的事務提供成為可能,因此我們將其稱之為事務提交樹(Transaction Commit Tree)。
一、事務登記(Transaction Enlisting)和事務提交樹(Transaction Commit Tree)
事務登記的目的在於建立起事務參與者(隻要指資源管理器和事務管理器DTC)之間的關係,促進相互之間的協作。我們先來看看整個事務登記是如何進行的,整個事務登記流程大致如圖1所示。
圖1 事務登記的流程
圖1所示的事務涉及到部署與兩台機器(Machine A和Machine B)上兩個服務之間的交互,事務由Service初始化,在調用Service2的時候被傳播到Machine B,從而將分布於兩台機器的資源管理器納入到同一個事務之中。接下來,我們對整個流程進行詳細介紹。
首先,Service A開始一個新的事務,並將其最為當前執行上下文的環境事務(Ambient Transaction)。當Service A調用本機的資源管理器的時候,會將該資源管理器納入到本事務之中(對於我們後續要介紹的System.Transactions事務,像SQL Server、Oracle以及MSMQ等資源管理器都能夠自動感知到當前的環境事務)。此時,資源管理器(RM)向本機的DTC進行事務登記,從此DTC和資源管理器之間建立起了上下級關係。
當Service A在調用Service B的時候,會將當前事務的一些信息,比如分布式事務的ID以及關於本機DTC相關信息,封裝在消息中(一般是SOAP報頭)向對方傳遞。當Service B接受到服務調用請求消息,會將事務相關的信息提取出來在本地重建事務,並將其作為當前的環境事務,該事務和原事務具有相同的ID。同時,根據得到的關於Machine A的DTC相關信息,讓本機的DTC對Machine A的DTC進行事務登記,進而使兩台機器的DTC確立了上下級關係。
和Service A訪問本機的資源管理器一樣,Machine B的資源管理器被Service B調用並被納入當前事務的時候,會向本機DTC進行事務登記。
當上麵所述的事務登記流程結束後,參與整個分布式事務的DTC和資源管理器形成了如圖2所示的樹形層次結構,由於該結構的構建主要是為了後麵對整個事務的提交服務的,所以我們一般將其稱為事務提交樹(Transaction Commit Tree)。事務提交樹的根為事務初始化服務所在機器的DTC,在整個事務提交過程中,它是總的協調者,又被稱為全局提交協調器(GCC:Global Commit Coordinator )。資源管理器充當事務提交樹的葉子節點,它們的父節點為本機的DTC。分布於不同機器的DTC按照事務傳播的路徑形成上下級關係。
圖2 事務提交樹
事務提交樹的構建使得對分布式事務的提交成為可能,分布式事務的提交采用兩階段協議實現,接下來我們詳細介紹基於兩階段提交協議的事務提交機製。
二、基於兩階段提交(2PC:Two-Phase Commit)協議的事務提交機製
不同於基於單一資源管理器的本地事務,在一個分布式環境中時實現一個涉及到多個資源管理器的分布式事務,實現事務的ACID四大屬性,要麻煩得多。當事務初始化服務(應用或者組件,為了更佳貼近WCF,我們都稱服務)完成所有相關的操作,決定提交該事務。對於分布式事務的提交,最終的結果有兩個:如果所有的操作能夠順利完成,需要持久化的數據被相應的資源管理器寫入到目標資源;如果任何一個環節失敗,所有持久化資源管理器將數據恢複到原來的狀態。分布式事務的整個提交過程,采用兩階段提交(2PC:Two-Phase)Commit協議完成。顧名思義,“兩階段提交”意味整個整個事務提交階段分兩個階段,我們現在就來詳細介紹分別在這兩個階段中,都在做些什麼。
注:在事務初始化服務決定提交事務之前,任何一個參與者均可以中止(Abort)該事務,任何一個參與者對事務的中止都將導致整個分布式事務的回滾。
1、第一階段(Phase I):準備(Prepare)階段
在第一個階段,作為根節點的DTC沿著事務提交樹的路徑,向所有事務的參與者發起請求,要求它們對本地事務的結果進行投票。被請求的參與者將本地事務結果返回給自己的上級,對於資源管理器,自己的上級就是本機的DTC;如果自己本身就是DTC,那麼自己得上級就是位於事務提交樹父節點的DTC。根據具體事務操作執行的情況,參與者投票的類型包括如下三種:
- 就緒(Prepared):參與者同意對事務的提交,並承諾在接收到真正的提交請求後完成本地的提交任務;
- 隻讀(Read-only):參與者同意對事務的提交,但是不希望接收真正的事務提交請求;
- 中止(Aborted):參與者要求中止事務。
對於一個非根節點DTC來說,當它從父節點接收到標準的“準備”請求後,會立即將該請求沿著事務提交樹發送給自己的下級(本機的資源管理器和下級DTC),然後根據從下級接收的所有投票結果,計算出自己投票的結果。具體的算法是:如果所有的投票結果都是“就緒”和“隻讀”,對應的結果是“提交”,反之,如果任何一個投票結果是“中止”,則最終的結果就是“中止”,換句話說,任何一個事務參與者具有一票否決權最後。最後,DTC將計算出來的投票結果反饋給自己的上級。
當根節點DTC接收到隸屬於自己的所有資源管理器和下級DTC的投票結果後,采用於上麵一樣的算法決定整個分布式事務的最終結果。當根節點DTC決定了事務最終的結果後,整個提交過程進入第二階段。
注:我們可以設置事務的超時時限,如果根節點DTC在該時限內沒有介紹到所有參與者的投票請求,會對整個分布式事務做出回滾的決定。
2、第二階段(Phase II):提交(Commit)或中止(Abort)
作為事務提交樹根節點的DTC根據最終的事務結果,對整個事務進行最終的提交或者中止操作。同樣是沿著事務提交樹的路徑,提交或者中止請求被廣播出去。相應的資源管理器根據從本機DTC獲得的請求,實施最終的提交或者恢複操作。當事務參與者完成了各自就的任務後,類似於第一個階段的投票,會講執行的結果沿著事務提交樹逆向回饋給作為根節點的DTC。
根節點DTC隻有接收到所有事務參與者的基於各自事務處理的回複,才能確保整個事務被成功提交或者回滾。那麼如果事務的參與者完成了第一階段的投票,網絡斷開,那將如何呢?這就涉及到對未決(In-Doubt)事務的處理。
3、未決(In-Doubt)事務的處理
對於某個分布式事務的參與者(DTC或者資源管理器)來說,在第一階段向上級(事務提交樹的父節點)投票表明提交就緒(Prepared)之後,直到它接收到根節點DTC最終的提交或者回滾的請求,它並不知曉本地事務的結果。在這期間,如果出現當機並重啟,本地的事務處於一種“未決(In-Doubt)”狀態。未決事務僅僅出現在非根節點DTC所在的機器。分布式事務采用如下的機製處理未決事務。
當重啟後,對於本機的所有未決事務,DTC會向上級DTC發送查詢請求,獲取每一個事務最終的結果(提交還是中止)。如果上級也不能決定事務的結果,那麼請求會沿著事務提交樹不斷向上(沿著根的方向)發送,直到得到一個明確的答複(不管怎樣,位於根節點的全局提交協調器總是清楚事務的結果的)。
此外,當下級DTC向自己發送相同的查詢請求的時候,該DTC會講獲取到的結果回複給它們。如果未決事務存在的時間太長,係統管理者可以強製提交或者中止該事務。
4、單階段提交(SPC: Single-Phase Commit)優化
對於事務最終結果(提交或者中止)的決策者來說,如果它具有了不止一個下級,那麼采用基於投票機製的兩階段提交協議唯一選擇。但是如果僅僅具有一個唯一的下級呢,這種投票機製就沒有必要了。在這種情況下,根節點DTC采用一種優化的協議來完成整個事務的提交,我們稱之為單階段提交(SPC:Single-Phase Commit)。
顧名思義,2PC意味著整個事務提交分成兩個階段,SPC則表示將其所短為一個階段。整個流程很簡單,如果根節點DTC僅僅隻有一個登記的事務參與者(本機資源管理器或者下級DTC),而不管這個下級自身具有幾個下級,它不會像2PC一樣先向下級發送“準備”請求,而是直接發送提交請求,我們將這個請求成為單階段提交(SPC)請求。接收到SPC請求的參與者,如果是資源管理器,則直接提交本地事務,並將最終結果(成功提交或者失敗中止)反饋給這個跟節點DTC。
如果SPC請求的接收者是DTC,那麼會根據隸屬於自己的下級的數量選擇相應的提交策略。具體做法和根節點DTC提交策略的選擇方式一樣:如果自己具有唯一一個下級,則采用SPC,反之采用2PC。
也就是說,不僅僅是根節點DTC可以選擇SPC提交事務,任何具有單一下級的DTC均可以采用SPC。但是,非根節點DTC隻有在接收到SPC請求的情況下,才能選擇通過SPC提交事務。如圖3給出了兩顆事務提交樹(圖中忽略掉資源管理器,每個節點代表DTC),對於左邊的樹,因為根節點A和下級B均隻有一個唯一的下級,所以A和B均采用SPC,C具有兩個下級,則采用2PC。而對於右邊的樹,因為根節點本身具有兩個下級,決定了所有的節點均采用2PC,即使是對於隻有一個下級的B和C。
圖3 DTC對SPC和2PC的選擇
我們我們介紹整個Windows平台基於DTC的分布式事務管理模型,接下來的一篇中,我將會詳細介紹基於System.Transactions事務的編程。
分布式事務係列:
談談分布式事務之一:SOA需要怎樣的事務控製方式
談談分布式事務之二:基於DTC的分布式事務管理模型[上篇]
談談分布式事務之二:基於DTC的分布式事務管理模型[下篇]
談談分布式事務之三: System.Transactions事務詳解[上篇]
談談分布式事務之三: System.Transactions事務詳解[下篇]
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-27 16:33:58