這一幾天一直在回顧事務相關的知識,也準備把之前瞭解皮毛的知識進行一些深刻總結,雖然這一些知識並無用到,可是瞭解其實現原理仍是頗有必要的,由於知道了原理,你也能把它實現出來。java
在上一節事務的編程模型裏面,主要說明了三種編程模型,通常狀況下,咱們都接觸的是單一資源的事務,也就是單獨對一個數據庫進行操做。若是須要跨多個資源保證事務一致性數據庫
舉個例子:在ATM機取錢的時候,須要對用戶的帳戶進行扣款處理,而後發送一條消息給消息服務器(假設消息服務器是用JMS實現的),由消息服務器異步經過短信通知用戶。若是用戶取款失敗,那麼消息服務器不該該發送短信給用戶。如何保證 用戶賬務扣款 和 消息服務器的消息保持一致性,也就是說 取款成功,消息服務器就持久化消息,而後發送短信給用戶,取款失敗,消息服務器就回滾消息,啥都不作。編程
在上面這種狀況下,就須要使用分佈式事務,也就是跨越多個資源的保證數據一致性。服務器
X/Open DTP(X/Open Distributed Transaction Processing Reference Model) 是X/Open 這個組織定義的一套分佈式事務的標準,也就是了定義了規範和API接口,由這個廠商進行具體的實現。這個思想在java 平臺裏面處處都是。異步
X/Open DTP 定義了三個組件: AP,TM,RM分佈式
AP(Application Program):也就是應用程序,能夠理解爲使用DTP的程序spa
RM(Resource Manager):資源管理器,這裏能夠理解爲一個DBMS系統,或者消息服務器管理系統,應用程序經過資源管理器對資源進行控制。資源必須實現XA定義的接口線程
TM(Transaction Manager):事務管理器,負責協調和管理事務,提供給AP應用程序編程接口以及管理資源管理器3d
其中,AP 能夠和TM 以及 RM 通訊,TM 和 RM 互相之間能夠通訊,DTP模型裏面定義了XA接口,TM 和 RM 經過XA接口進行雙向通訊,例如:TM通知RM提交事務或者回滾事務,RM把提交結果通知給TM。AP和RM之間則經過RM提供的Native API 進行資源控制,這個沒有進行約API和規範,各個廠商本身實現本身的資源控制,好比Oracle本身的數據庫驅動程序。blog
下面一幅圖說明了三者的關係:
其中在DTP定了如下幾個概念:
事務:一個事務是一個完整的工做單元,由多個獨立的計算任務組成,這多個任務在邏輯上是原子的。
全局事務:對於一次性操做多個資源管理器的事務,就是全局事務
分支事務:在全局事務中,某一個資源管理器有本身獨立的任務,這些任務的集合做爲這個資源管理器的分支任務
控制線程:用來表示一個工做線程,主要是關聯AP,TM,RM三者的一個線程,也就是事務上下文環境。簡單的說,就是須要標識一個全局事務以及分支事務的關係。
第一階段:準備階段
事務管理器通知資源管理器準備分支事務,資源管理器告之事務管理器準備結果
第二階段:提交階段
事務管理器通知資源管理器提交分支事務,資源管理器告之事務管理器結果
下面一幅圖演示了正常狀況下的兩階段提交,
若是第一階段某一個資源預提交失敗,第二階段就回滾第一階段已經預提交成功的資源
以上是比較正常的狀況,可是因爲RM有權利本身根據狀況提交或者回滾本身的分支事務(官方說法是:Heuristic Decision)那三麼就可能出現如下種狀況:
1 在TM通知RM提交事務以前,RM分支事務已經提交
2 在TM通知RM提交事務以前,RM分支事務所有回滾
3 在TM通知RM提交事務以前,RM分支事務部分回滾
對於Heuristic Decision標記的分支事務,在沒有TM通知RM forget 它以前,RM都必須保存分支事務的信息,等到TM從失敗中恢復事務以後,通知RM forget 分支事務,這個時候RM才真正的完成事務。
對於前面兩種狀況來講,TM會比較好處理,作事務恢復的時候,要麼標記全局事務成功,要麼標記全局事務回滾,通知RM能夠完成分支事務了。對於第三種狀況,可能就須要進行決策了,這個具體怎麼處理,貌似DTP並無說明細節,能夠交給應用本身去判斷。
DTP編程模型
雖然DTP內部的實現比較複雜,可是對於DTP編程模型就比較簡單了
1 AP經過TM獲取事務
2 AP申明須要哪些RM,TM註冊RM
3 AP使用RM完成分支事務
4 AP經過TM提交事務
5 TM通知RM提交事務
而DTP的服務的實現就須要考慮如下幾個問題:
其實若是把這幾個問題了解清楚了,就能夠本身實現一個兩階段提交的分佈式事務模型了。