前言
本文演示如何使用 Seata Starter 完成 Spring Cloud 应用的分布式事务接入,Feign远程调用,AT 模式为例。
Seata是 阿里巴巴 开源的分布式事务中间件,以 高效并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题。
准备
Seata服务端安装启动,请参考文章:《Centos7部署Seata分布式事务系统并以nacos为配置中心》
Feign的整合,请参考文章:《Spring Cloud Alibaba实战》系列-Feign之远程调用
如何开始
项目增加jar依赖
<!--Seata 分布式事务-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
在 resource 目录下增加注册文件 registry.conf
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
serverAddr = "111.231.111.150:8848"
namespace = ""
cluster = "default"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "111.231.111.150:8848"
namespace = ""
}
}
配置seata代理数据源,如果不配置,事务会不起作用
public class SeataAutoConfig {
private DataSourceProxy dataSourceProxy;
/**
* 主数据源
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.master")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
@Bean
@Primary
public DataSource dataSource() {
dataSourceProxy = new DataSourceProxy(druidDataSource());
return dataSourceProxy;
}
@Bean
public DataSourceProxy dataSourceProxy() {
return dataSourceProxy;
}
}
业务库中增加 undo_log 表
CREATE TABLE IF NOT EXISTS `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
yml配置(可选),不配置采取默认的也可以
# seata
seata:
client:
tm:
rollback:
retry:
# 一阶段全局回滚结果上报TC重试次数,默认1次,建议大于1
count: 3
commit:
retry:
# 一阶段全局提交结果上报TC重试次数,默认1次,建议大于1
count: 3
案例
新建两个springboot项目,gourd-hu(事务发起方) 和 gourd-sub,分别进行上述步骤。
接口准备
gourd-sub项目提供web接口:
gourd-hu项目准备feign调用接口,及测试方法入口:
方法入口上增加 @GlobalTransactional 注解,表示开启全局事务。
处理业务逻辑:
测试
项目集成启动成功标志,项目没有报错,并且出现下面的日志就可以了。
事务测试
事务异常情况:
发起者接口内通过feignClient 调用了sub 的两个接口,本地事务内模拟异常,测试分支事务的回滚情况。
异常抛出之前,本地事务未提交,所以log表没有记录,分支事务一阶段已结束,数据被修改,存在两条undoLog日志。
异常抛出之后,本地事务回滚,同时通知分支事务回滚数据,并异步删除undoLog。
事务正常结束情况:
发起者接口内通过feignClient 调用了sub 的两个接口,测试事务正常结束情况。
事务结束之前,本地事务未提交,所以log表没有记录,分支事务一阶段已结束,数据被修改,存在两条undoLog日志。
事务结束之后,本地事务提交,通知分支事务,异步删除undoLog。
结语
至此,springboot2.x 整合Seata 就结束啦,如果本文有错误的地方,欢迎评论指正。
===============================================
代码均已上传至本人的开源项目