本篇文章为大家展示了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模式,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/2555967/blog/5034715