一、描述:
隨着分布式服務的到來,分布式事務必然也就成為分布式的重點,因此了解tx-lcn很有必要
二、tx-lcn的TC與TM的交互圖:
注:其中事務發起方為TC-A,而TC-B、TC-C為事務參與方,TM為事務處理器:
交互描述:
1、TC-A向TM發送創建組請求
2、TC-B向TM發送加入組請求
3、TC-C向TM發送加入組請求
4、TC-B將調用結果返回TC-A
5、TC-B將事務狀態發送到TM
6、TC-C將調用結果返回TC-A
7、TC-C將事務狀態發送到TM
8、TC-A向TM發送事務完成通知
9、TM根據事務情況,分別向TC-A,TC-B,TC-C發送事務通知
二、各注解的適用:
1、@LCNTransaction:(一般用於mysql或oracle,在於支持事務場景)
代理本地connection連接,使用數據庫本身提供的commit或者rollback完成事務的提交或者回滾
2、@TCCTransaction:(一般用於redis,memcache)
不代理本地connection連接,以callback指定類,confirm、cancel指定類內的方法完成事務的提交或者回滾
3、@TXCTransaction:(一般用於mysql或oracle,在於不支持事務場景)
代理本地connection連接,將操作可影響到的數據先查詢緩存,通過TM的事務通知完成刪除備份數據或者恢復備份數據
4、@TXTransaction:
以上三個注解的抽象版,默認為@LCNTransaction
注:分布式事務的組合可以是LCN+LCN+LCN,TCC+TCC+TCC,TXC+TXC+TXC,LCN+TCC+TXC或者LCN+LCN(LCN+TCC+TXC)+TXC,也就是說可以任意組合、嵌套;
三、TM交互步驟:
TM的交互分三層:
第一層為接受TC的調用通知:
ServerRpcAnswer:callback();
第二層初始化通信數據:
(1):QueryTMClusterExecuteService
查詢已緩存的TM地址
(2):InitClientService
綁定TC的通信信息
第三層為TM和TC的事務交互層:
(1):CreateGroupExecuteService
創建事務組,開始分布式事務
(2):AcquireDTXLockExecuteService
獲取分布式鎖(一般用於TXC類型的事務)
(3):JoinGroupExecuteService
加入事務組
(4):NotifyGroupExecuteService
通知TC事務的狀態
(5):CleanInvalidTMExecuteService、
通知TC要求清空事務日志
(6):ReleaseDTXLockExecuteService
釋放分布式鎖(和獲取搭配使用)
(7):WriteTxExceptionExecuteService
將事務異常寫入本地日志
四、TC交互步驟:
TC的交互分三層:
第一層為獲取注解層:
如:TransactionAspect類的方法:
(1):代理標注@LCNTransaction注解的方法
@Pointcut("@annotation(com.codingapi.txlcn.tc.annotation.TxTransaction)")
public void txTransactionPointcut() {}
(2):代理標注@TCCTransaction注解的方法
@Pointcut("@annotation(com.codingapi.txlcn.tc.annotation.LcnTransaction)")
public void lcnTransactionPointcut() {}
(3):代理標注@TXCTransaction注解的方法
@Pointcut("@annotation(com.codingapi.txlcn.tc.annotation.TxcTransaction)")
public void txcTransactionPointcut() {}
(4):代理標注@TXTransaction注解的方法
@Pointcut("@annotation(com.codingapi.txlcn.tc.annotation.TccTransaction)")
public void tccTransactionPointcut() {}
第二層為代理connection層:
如:LcnTransactionResourceProxy類的方法:proxyConnection
如:TccTransactionResourceProxy類的方法:proxyConnection
如:TxcTransactionResourceProxy類的方法:proxyConnection
第三層為rpc交互層:
獲取事務管理類:
(1):如TC-A所示處於事務最外層:
使用(TCN|TCC|TXC)StartingTransaction作為事務的代理層包含三部分內容:
preBusinessCode:創建組並代理本地connection,如createGroup,makeProxy
onBusinessCodeError|onBusinessCodeSuccess:記錄或清空本地事務狀態
postBusinessCode:發送事務狀態通知,如notifyGroup
(2):如TC-B、TC-C所示處於事務內層(這里假設TC-A、TC-B、TC-C處於同一個應用系統):
使用(TCN|TCC|TXC)RunningTransaction作為事務的代理層包含三部分內容:
preBusinessCode:代理本地connection,如makeProxy
onBusinessCodeError:清空本地事務日志記錄
onBusinessCodeSuccess:加入組,如joinGroup
進行交互:
交互執行類:DTXServiceExecutor:
交互方法transactionRunning:
//被代理方法執行前操作
dtxLocalControl.preBusinessCode(info);
//調用被代理的方法
dtxLocalControl.doBusinessCode(info);
//代理方法執行后操作
dtxLocalControl.onBusinessCodeSuccess(info, result);
//被代理執行出錯操作
dtxLocalControl.onBusinessCodeError(info, e);
//整個交互完成后操作
dtxLocalControl.postBusinessCode(info);
接收TM的調用:ClientRpcAnswer:callback()
//或是通知提交事務,或是通知回滾事務,或是通知刪除日志
注:參與分布式事務的每個服務需要分別建組,如果當前線程變量里面已經存有組,加入即可,否則需要創建組並存儲到線程變量內
五、存在的問題:
1、分布式事務的多個參與方不能保證在同一個事務組里面;
2、事務回滾過程對同一groupId的事務進行回滾,而同一groupId內的參與方只能在同一服務內