關於分佈式事務、兩階段提交、一階段提交、Best Efforts 1PC模式和事務補償機制的研究[轉]

1.XAjava

XA是由X/Open組織提出的分佈式事務的規範。XA規範主要定義了(全局)事務管理器(Transaction Manager)和(局部)資源管理器(Resource Manager)之間的接口。XA接口是雙向的系統接口,在事務管理器(Transaction Manager)以及一個或多個資源管理器(Resource Manager)之間造成通訊橋樑。XA之因此須要引入事務管理器是由於,在分佈式系統中,從理論上講(參考Fischer等的論文),兩臺機器理論上沒法達到一致的狀態,須要引入一個單點進行協調。事務管理器控制着全局事務,管理事務生命週期,並協調資源。資源管理器負責控制和管理實際資源(如數據庫或JMS隊列)。下圖說明了事務管理器、資源管理器,與應用程序之間的關係:web

 

圖1.XA規範下的分佈式事務各種參與者之間的關係spring

 

2.JTA數據庫


做爲java平臺上事務規範JTA(Java Transaction API)也定義了對XA事務的支持,實際上,JTA是基於XA架構上建模的,在JTA 中,事務管理器抽象爲javax.transaction.TransactionManager接口,並經過底層事務服務(即JTS)實現。像不少其餘的java規範同樣,JTA僅僅定義了接口,具體的實現則是由供應商(如J2EE廠商)負責提供,目前JTA的實現主要由如下幾種:緩存


1.J2EE容器所提供的JTA實現(JBoss)
2.獨立的JTA實現:如JOTM,Atomikos.這些實現能夠應用在那些不使用J2EE應用服務器的環境裏用以提供分佈事事務保證。如Tomcat,Jetty以及普通的java應用。服務器

 

3.兩階段提交網絡


全部關於分佈式事務的介紹中都必然會講到兩階段提交,由於它是實現XA分佈式事務的關鍵(確切地說:兩階段提交主要保證了分佈式事務的原子性:即全部結點要麼全作要麼全不作)。所謂的兩個階段是指:第一階段:準備階段和第二階段:提交階段。架構

 

圖2.兩階段提交示意圖(摘自info發佈的《java事務設計策略》一文)併發



1.準備階段:事務協調者(事務管理器)給每一個參與者(資源管理器)發送Prepare消息,每一個參與者要麼直接返回失敗(如權限驗證失敗),要麼在本地執行事務,寫本地的redo和undo日誌,但不提交,到達一種「萬事俱備,只欠東風」的狀態。(關於每個參與者在準備階段具體作了什麼目前我尚未參考到確切的資料,可是有一點很是肯定:參與者在準備階段完成了幾乎全部正式提交的動做,有的材料上說是進行了「試探性的提交」,只保留了最後一步耗時很是短暫的正式提交操做給第二階段執行。)

2.提交階段:若是協調者收到了參與者的失敗消息或者超時,直接給每一個參與者發送回滾(Rollback)消息;不然,發送提交(Commit)消息;參與者根據協調者的指令執行提交或者回滾操做,釋放全部事務處理過程當中使用的鎖資源。(注意:必須在最後階段釋放鎖資源)

將提交分紅兩階段進行的目的很明確,就是儘量晚地提交事務,讓事務在提交前儘量地完成全部能完成的工做,這樣,最後的提交階段將是一個耗時極短的微小操做,這種操做在一個分佈式系統中失敗的機率是很是小的,也就是所謂的「網絡通信危險期」很是的短暫,這是兩階段提交確保分佈式事務原子性的關鍵所在。(惟一理論上兩階段提交出現問題的狀況是當協調者發出提交指令後當機並出現磁盤故障等永久性錯誤,致使事務不可追蹤和恢復)

從兩階段提交的工做方式來看,很顯然,在提交事務的過程當中須要在多個節點之間進行協調,而各節點對鎖資源的釋放必須等到事務最終提交時,這樣,比起一階段提交,兩階段提交在執行一樣的事務時會消耗更多時間。事務執行時間的延長意味着鎖資源發生衝突的機率增長,當事務的併發量達到必定數量的時候,就會出現大量事務積壓甚至出現死鎖,系統性能就會嚴重下滑。這就是使用XA事務

4.一階段提交(Best Efforts 1PC模式)

不像兩階段提交那樣複雜,一階段提交很是直白,就是從應用程序向數據庫發出提交請求到數據庫完成提交或回滾以後將結果返回給應用程序的過程。一階段提交不須要「協調者」角色,各結點之間不存在協調操做,所以其事務執行時間比兩階段提交要短,可是提交的「危險期」是每個事務的實際提交時間,相比於兩階段提交,一階段提交出如今「不一致」的機率就變大了。可是咱們必須注意到:只有當基礎設施出現問題的時候(如網絡中斷,當機等),一階段提交纔可能會出現「不一致」的狀況,相比它的性能優點,不少團隊都會選擇這一方案。關於在spring環境下如何實現一階段提交,有一篇很是優秀的文章值得參考

5.事務補償機制mvc


像best efforts 1PC這種模式,前提是應用程序能獲取全部的數據源,而後使用同一個事務管理器(這裏指是的spring的事務管理器)管理事務。這種模式最典型的應用場景非數據庫sharding莫屬。可是對於那些基於web service/rpc/jms等構建的高度自治(autonomy)的分佈式系統接口,best efforts 1PC模式是無能爲力的,此類場景下,還有最後一種方法能夠幫助咱們實現「最終一致性」,那就是事務補償機制。關於事務補償機制是一個大話題,本文只簡單說起,之後會做專門的研究和介紹。

 

6.在基於兩階段提交的標準分佈式事務和Best Efforts 1PC二者之間如何選擇

通常而言,須要交互的子系統數量較少,而且整個系統在將來不會或不多引入新的子系統且負載長期保持穩定,即無伸縮要求的話,考慮到開發複雜度和工做量,能夠選擇使用分佈式事務。對於時間需求不是很緊,對性能要求很高的系統,應考慮使用Best Efforts 1PC或事務補償機制。對於那些須要進行sharding改造的系統,基本上不該再考慮分佈式事務,由於sharding打開了數據庫水平伸縮的窗口,使用分佈式事務看起來好像是爲新打開的窗口又加上了一把枷鎖。

補充:關於網絡通信的危險期

因爲網絡通信故障隨時可能發生,任何發出請求後等待迴應的程序都會有失去聯繫的危險。這種危險發生在發出請求以後,服務器返回應答以前,若是在這個期間網 絡通信發生故障,發出請求一方沒法收到迴應,因而沒法判斷服務器是否已經成功地處理請求,由於收不到迴應多是請求沒有成功地發送到服務器,也多是服務 器處理完成後的迴應沒法傳回請求方。這段時間稱爲網絡通信的危險期(In-doubt Time)。很顯然,網絡通信的危險期是分佈式系統除單點可靠性以外須要考慮的另外一個可靠性問

框架/平臺構成:
Maven+Springmvc + Mybatis + Shiro(權限)+ Tiles(模板) +ActiveMQ(消息隊列) + Rest(服務) + WebService(服務)+ EHcache(緩存) + Quartz(定時調度)+ Html5(支持PC、IOS、Android)

用戶權限系統:
組織結構:角色、用戶、用戶組、組織機構;權限點:頁面、方法、按鈕、數據權限、分級受權

項目管理新體驗:
快速出原型系統、組件樹、版本控制、模塊移植、協同開發、實時監控、發佈管理

可持續集成:
全部組件可移植、可定製、可擴充,開發成果不斷積累,造成可持續發展的良性循環

支持平臺平臺: 
Windows XP、Windows 7 、Windows 10 、 Linux 、 Unix

服務器容器:
Tomcat 5/6/7 、Jetty、JBoss、WebSphere 8.5 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

 

JEESZ通用版本分佈式模塊化開發平臺 - zookeeperflume - zookeeperflume的博客

相關文章
相關標籤/搜索