您好,登錄后才能下訂單哦!
本篇文章為大家展示了seata中如何使用AT和TCC模式,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
圖片來自 Seata解析-TM、RM、TC交互流程梳理
維護全局和分支事務的狀態,驅動全局事務提交或回滾。
定義全局事務的范圍:開始全局事務、提交或回滾全局事務。
管理分支事務處理的資源,與TC交談以注冊分支事務和報告分支事務的狀態,并驅動分支事務提交或回滾。
基于支持本地 ACID 事務的關系型數據庫。
Java 應用,通過 JDBC 訪問數據庫。
兩階段提交協議的演變:
一階段:業務數據和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源。
二階段:
提交異步化,非常快速地完成。
回滾通過一階段的回滾日志進行反向補償。
一個分布式的全局事務,整體是 兩階段提交 的模型。全局事務是由若干分支事務組成的,分支事務要滿足 兩階段提交 的模型要求,即需要每個分支事務都具備自己的:
一階段 prepare 行為
二階段 commit 或 rollback 行為
TCC 模式,不依賴于底層數據資源的事務支持:
一階段 prepare 行為:調用 自定義 的 prepare 邏輯。
二階段 commit 行為:調用 自定義 的 commit 邏輯。
二階段 rollback 行為:調用 自定義 的 rollback 邏輯。
所謂 TCC 模式,是指支持把 自定義 的分支事務納入到全局事務的管理中。
參照官網部署教程,啟動成功后可以看到這句 Server started, listen port: 8091
,注意這個端口不是用來通過http訪問的, 這個端口是用來協調應用分布式事務的,直接通過瀏覽器訪問會報錯。
SLF4J: A number (18) of logging calls during the initialization phase have been intercepted and are SLF4J: now being replayed. These are subject to the filtering rules of the underlying logging system. SLF4J: See also http://www.slf4j.org/codes.html#replay 09:54:04.048 INFO --- [ main] io.seata.config.FileConfiguration : The file name of the operation is registry 09:54:04.055 INFO --- [ main] io.seata.config.FileConfiguration : The configuration file used is C:\Server\seata-server-1.4.2\conf\registry.conf 09:54:04.119 INFO --- [ main] io.seata.config.FileConfiguration : The file name of the operation is file.conf 09:54:04.119 INFO --- [ main] io.seata.config.FileConfiguration : The configuration file used is C:\Server\seata-server-1.4.2\conf\file.conf 09:54:06.578 INFO --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited 09:54:07.304 INFO --- [ main] i.s.core.rpc.netty.NettyServerBootstrap : Server started, listen port: 8091
<!-- 分布式事務seata --> <dependency> <groupid>com.alibaba.cloud</groupid> <artifactid>spring-cloud-starter-alibaba-seata</artifactid> </dependency> <!-- 序列化方式選擇的kryo, 在使用jackson和fastjson時,對時間的序列化一直出問題 --> <dependency> <groupid>de.javakaffee</groupid> <artifactid>kryo-serializers</artifactid> <version>${kryo.serializers.version}</version> </dependency>
seata: service: # TC服務列表 僅注冊中心為file時使用 grouplist: default : seata.server.cn:8091 # 事務群組, service-goods-center為分組,配置項值為TC集群名 vgroup-mapping: service-goods-center: default # 全局事務開關,默認false。false為開啟,true為關閉 disable-global-transaction: false # 視作分名 tx-service-group: service-goods-center client: undo: # undolog的序列化方式, AT模式需要配置,因為AT模式數據庫會有undo-log表 log-serialization: kryo
訪問 seata數據庫腳本 鏈接,找到對應版本和對應數據庫類型的SQL腳本,在業務系統創建出來undo-log
表。
1.3.0版本
CREATE TABLE IF NOT EXISTS `undo_log` ( `branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id', `xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id', `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization', `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info', `log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status', `log_created` DATETIME(6) NOT NULL COMMENT 'create datetime', `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime', UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
只需要在TM端服務方法上加上@GlobalTransactional
注解,被調用RM端方法可以不用顯式的聲明@GlobalTransactional
注解
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) public String insert() { service.insert(); //放開以下注解拋出異常 //throw new RuntimeException("服務AT測試回滾"); return "success"; }
@LocalTCC
一定需要注解在接口上,否則不生效,此接口可以是尋常的業務接口,只要實現了TCC的兩階段提交對應方法便可,TCC相關注解如下:
@LocalTCC
適用于SpringCloud+Feign模式下的TCC
@TwoPhaseBusinessAction
注解try方法,其中name為當前tcc方法的bean名稱,寫方法名便可(全局唯一),commitMethod指向提交方法,rollbackMethod指向事務回滾方法。指定好三個方法之后,seata會根據全局事務的成功或失敗,去幫我們自動調用提交方法或者回滾方法。
@BusinessActionContextParameter
注解可以將參數傳遞到二階段(commitMethod/rollbackMethod)的方法。
BusinessActionContext
便是指TCC事務上下文
/** * 這里定義tcc的接口 * 這些一定要定義在接口上 * 我們使用springCloud的遠程調用 * 那么這里使用LocalTCC便可 * * @author tanzj */ @LocalTCC public interface TccService { /** * 定義兩階段提交 * name = 該tcc的bean名稱,全局唯一 * commitMethod = commit 為二階段確認方法 * rollbackMethod = rollback 為二階段取消方法 * BusinessActionContextParameter注解 傳遞參數到二階段中 * */ @TwoPhaseBusinessAction(name = "insert", commitMethod = "commitTcc", rollbackMethod = "cancel") String insert( @BusinessActionContextParameter(paramName = "params") Map<string, string> params ); /** * 確認方法、可以另命名,但要保證與commitMethod一致 * context可以傳遞try方法的參數 * 參數是固定的, 不可以增加或減少, */ boolean commitTcc(BusinessActionContext context); /** * 二階段取消方法 * 參數是固定的, 不可以增加或減少 */ boolean cancel(BusinessActionContext context); }
在try方法中使用@Transational
可以直接通過spring事務回滾關系型數據庫中的操作,而非關系型數據庫等中間件的回滾操作可以交給rollbackMethod方法處理。
使用context.getActionContext("params")便可以得到一階段try中定義的參數,在二階段對此參數進行業務回滾操作。
**注意1:**此處亦不可以捕獲異常(同理切面處理異常),否則TCC將識別該操作為成功,二階段直接執行commitMethod。
**注意2:**TCC模式要開發者自行保證冪等和事務防懸掛
調用代碼
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) public String insert() { log.info("xid = " + RootContext.getXID()); //todo 實際的操作,或操作MQ、redis等 tccDAO.insert(new HashMap<>()); //放開以下注解拋出異常 //throw new RuntimeException("服務tcc測試回滾"); return "success"; }
也沒別的,默認使用的就是AT事務,別在同一個接口方法上添加TCC注解就行,可以通過AT方法嵌套TCC方法,注意不要通過this.xx()調用,這樣會無法應用代理的增強。
mybatis-plus
出現問題,解決方案透過源碼解決SeataAT模式整合Mybatis-Plus失去MP特性的問題</string,>
上述內容就是seata中如何使用AT和TCC模式,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。