EasyTransaction是一個全功能的分佈式事務框架,如下特性摘抄自其首頁:https://github.com/QNJR-GROUP/EasyTransactionhtml
本文主要分享EasyTransaction core中各個package的做用其主要實現。git
請先閱讀 Seata架構的比對思考 http://www.javashuo.com/article/p-xetvolvp-u.html ,再結合 代碼以及demo調試過程看這篇,直接看的話這裏的點太零碎了github
主要類數據庫
LogProcessContext
其用於存儲ET事務的上下文信息。在開啓ET事務(第一次ET遠程調用,或者主動調用startSoftTrans方法)時,將建立本類的實例並將其與Spring的本地事務上下文綁定,經過:架構
TransactionSynchronizationManager.bindResource()
執行綁定。當須要取得ET上下文時,經過併發
TransactionSynchronizationManager.getResource()
取得。app
ET上下文中包含的主要內容有:框架
本包主要類爲異步
EasyTransFacade TransactionHook ConsistentGuardian ExecuteCacheManager
其定義了業務調用方的接口,只包含兩個:分佈式
public void startEasyTrans(String busCode,long trxId); public <P extends EasyTransRequest<R,E>,E extends EasyTransExecutor, R extends Serializable> Future<R> execute(P params);
第一個用於開啓全局事務,主要的操做爲:
第二個表示執行某個遠程事務方法。
基於註解的接口調用也是經過這兩個方法封裝而成。
其爲ET框架代碼與Spring原生事務的主要交界點,ET經過TransactionSynchronization定義的方法,在Spring本地事務執行過程當中,擴展支持了全局事務。主要擴展瞭如下兩個方法
beforeCommit(boolean readOnly) afterCompletion(int status)
beforeCommit方法將會
afterCompletion方法將會
本類用於處理ET全局事務的最終一致,例如TCC的Conifrim/Cancel,可靠消息的發送消息。
最終一致處理一般會在同步操做(TCC的TRY等)對應的本地事務執行完成後拋到線程池異步執行,但執行失敗的話,會有兜底的補償(recovery包),後續再詳細講述
該類的主要工做機制是根據以前寫入的全局事務日誌,獲取日誌對應的處理器(如從TCC的事務日誌獲取對應的TCC日誌處理器),以此
本類主要服務於ET的如下指望
其主要實現的是,
主要包含如下兩個接口,其主要做用於業務數據源。
DataSourceSelector TransStatusLogger
該類主要用於獲取當前事務/請求對應的數據源及其事務管理器,若應用有多個業務數據源,則須要自行實現對應的數據源選擇器,主要包含如下方法
DataSource selectDataSource(String appId,String busCode,long trxId); DataSource selectDataSource(String appId,String busCode,EasyTransRequest<?, ?> request);
第一個方法是開啓ET事務時候選擇對應的數據源
第二個方法是被調用方接受到請求時選擇對應的數據源(用於冪等、防懸掛處理,若不須要可忽略)
該接口包含一個默認實現,當只有單數據源時,能夠直接用該實現
SingleDataSourceSelector
該類主要用來讀寫用於判斷ET事務狀態的記錄,該記錄會在ET事務開啓時,寫入當前的數據庫表中,隨着業務對應事務(Spring本地事務)提交而提交,回滾而回滾。
更具體請直接看實現
該包存儲的是事務發起方(遠程服務調用方)相關處理類的位置,不一樣的事務類型(TCC,可靠事務等)有不一樣的Executor,以TCC爲例講解,其餘的事務類型實現都相似。
該類實現了三個接口
EasyTransExecutor接口定義了方法
<P extends EasyTransRequest<R,E>,E extends EasyTransExecutor,R extends Serializable> Future<R> execute(Integer sameBusinessCallSeq, P params);
該方法供類EasyTransFacade.execute使用,其對應的是執行TCC裏的TRY方法,具體的,它
LogProcessor接口定義瞭如何處理事務日誌,其包含一個主要方法
boolean logProcess(LogProcessContext ctx, Content currentContent)
該方法將會判斷,若是傳入的日誌類型是PreTccCallContent(TCC TRY請求對應的日誌)的話,將會監聽該日誌最終的配對信息(類ConsistentGuardian會在處理當前ET事務的日誌後,發送消息,告知全部須要配對的日誌的配對結果),若是
其餘的事務形態的實現也相似,再也不贅述
用於兜底恢復事務,實現最終一致。
代碼不復雜,能夠自行查看。
該包主要用於實現ET對應的Filter,該Filter做用於被調用端。咱們能夠經過實現ET的Filter擴展被調用端的功能,如處理冪等、處理嵌套事務、增長調用上下文的處理等等。
實現冪等、方懸掛等處理對應的包
冪等及防懸掛處理的主要原理:
用於生成ET的分佈式事務ID,當自行制定ID時,本包對應的方法不會被調用。當不指定ID時,將會自動生成一個。
定義ET事務日誌對應的Class,以及其讀寫接口。
事務日誌在以前TccExecutor等章節已提到,再也不贅述。
須要擴展事務日誌存儲實現的,直接實現如下接口便可
TransactionLogReader TransactionLogWritter
(ET事務日誌的讀寫不須要與業務事務在同一個事務中,也不能在同一個事務中)
用於在同一個appId中選擇一個做爲master進行兜底最終一致補償的包。
實際上選擇不須要太精確,任意一個appId下的實例都可,也能夠同時有多個master存在(但目前沒有意義,也會浪費性能)
用於提供ET實例狀態的包,可供Dashboard,監控等擴展使用
供客戶直接定義分佈式事務服務的包,其包含一些客戶直接使用的 父類、配置接口、配置註解等
從Spring中獲取並存儲對應的bean實現,以便於快速方便地經過ET對應的定義,取得對應bean
若要擴展新增對應的消息隊列實現,則實現這個包對應的接口
同上
ET框架所使用的序列化形式,可自行擴展
用於壓縮字符串,將字符串替換爲數字id,以提升存儲效率