springcloud整合seata
1、前置安装与了解:
1、nacos的安装:docker安装nacos并挂载
2、seata的安装:docker安装seata并挂载,同时注册到nacos
3、spring-boot版本为2.6.12,spring-cloud-alibaba版本为2021.0.4.0,spring-cloud版本为2021.0.4
1.1 事务分组如何找到后端Seata集群?
- 首先应用程序(客户端)中配置了事务分组(GlobalTransactionScanner 构造方法的txServiceGroup参数)。若应用程序是SpringBoot则通过seata.tx-service-group 配置
- 应用程序(客户端)会通过用户配置的配置中心去寻找service.vgroupMapping .[事务分组配置项],取得配置项的值就是TC集群的名称。若应用程序是SpringBoot则通过seata.service.vgroup-mapping.事务分组名=集群名称 配置
- 拿到集群名称程序通过一定的前后缀+集群名称去构造服务名,各配置中心的服务名实现不同(前提是Seata-Server已经完成服务注册,且Seata-Server向注册中心报告cluster名与应用程序(客户端)配置的集群名称一致)
- 拿到服务名去相应的注册中心去拉取相应服务名的服务列表,获得后端真实的TC服务列表(即Seata-Server集群节点列表)
2、在pom引入jar
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
3、在application.yml添加配置信息
注意:配置与默认一致的可以不要,我这里是为了记录特意写出来
seata:
# 默认为true
enabled: true
# 开启数据源自动代理 默认为true
enable-auto-data-source-proxy: true
# 事务模式 默认AT
data-source-proxy-mode: AT
# 事务分组配置(在v1.5之后默认值为default_tx_group)
tx-service-group: my_at_group
service:
# 指定事务分组至集群映射关系(右侧的集群名需要与Seata-server注册到Nacos的cluster保持一致)
vgroup-mapping:
my_at_group: default
registry:
type: nacos
nacos:
server-addr: 192.168.56.10:8848
application: seata-server
group: DEFAULT_GROUP
username: nacos
password: nacos
- tx-service-group: 定义事务分组,可以自定义,多个微服务只有在同一个事务分组中,分布式事务才能生效,也就是多个微服务该参数要保持一致;
- servicevgroup-mapping: 定义该事务分组连接的seata服务端集群的名称,该名称需要和seata server 定义的集群名称保持一致;
4、项目使用
4.1 AT 模式使用:
seata 客户端的事务模式默认使用AT 模式;通过以下两个步骤配置就可使用:
- 在每个客户端数据库中增加undo_log 表,用于AT 模式事务日志记录使用:
CREATE TABLE `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=8 DEFAULT CHARSET=utf8;
- 在对应的业务实现中增加@GlobalTransactional 注解
4.2 XA 模式使用
mysql 开启XA协议:
# 查询是否开启XA协议
SHOW VARIABLES LIKE 'innodb_support_xa';
如果没有开通,则打开 MySQL 配置文件 my.cnf 或 my.ini。在文件中找到 [mysqld] 部分,并在该部分下添加以下行:
[mysqld]
innodb_support_xa = 1
保存配置文件并重启 MySQL 服务;
显示设置模式为XA 模式,代码层面无需变动;
在application.yml修改
seata:
# 事务模式 默认AT
data-source-proxy-mode: XT
4.2 TCC模式使用
区别于在 AT 模式直接使用数据源代理来屏蔽分布式事务细节,业务方需要自行定义 TCC 资源的“准备”、“提交”和“回滚” 。比如在下方的例子中,
public interface TccActionOne {
@TwoPhaseBusinessAction(name = "DubboTccActionOne", commitMethod = "commit", rollbackMethod = "rollback")
public boolean prepare(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "a") String a);
public boolean commit(BusinessActionContext actionContext);
public boolean rollback(BusinessActionContext actionContext);
}
Seata 会把一个 TCC 接口当成一个 Resource,也叫 TCC Resource。在业务接口中核心的注解是 @TwoPhaseBusinessAction,表示当前方法使用 TCC 模式管理事务提交,并标明了 Try,Confirm,Cancel 三个阶段。name属性,给当前事务注册了一个全局唯一的的 TCC bean name。同时 TCC 模式的三个执行阶段分别是:
- Try 阶段,预定操作资源(Prepare) 这一阶段所以执行的方法便是被 @TwoPhaseBusinessAction 所修饰的方法。如示例代码中的 prepare 方法。
- Confirm 阶段,执行主要业务逻辑(Commit) 这一阶段使用 commitMethod 属性所指向的方法,来执行Confirm 的工作。
- Cancel 阶段,事务回滚(Rollback) 这一阶段使用 rollbackMethod 属性所指向的方法,来执行 Cancel 的工作。
其次,可以在 TCC 模式下使用 BusinessActionContext 在事务上下文中传递查询参数。如下属性:
- xid 全局事务id
- branchId 分支事务id
- actionName 分支资源id,(resource id)
- actionContext 业务传递的参数,可以通过 @BusinessActionContextParameter 来标注需要传递的参数。
在定义好 TCC 接口之后,我们可以像 AT 模式一样,通过 @GlobalTransactional 开启一个分布式事务。
@GlobalTransactional
public String doTransactionCommit(){
tccActionOne.prepare(null,"one");
tccActionTwo.prepare(null,"two");
}
注意,如果 TCC 参与者是本地 bean(非远程RPC服务),本地 TCC bean 还需要在接口定义中添加 @LocalTCC 注解,比如,
@LocalTCC
public interface TccActionTwo {
@TwoPhaseBusinessAction(name = "TccActionTwo", commitMethod = "commit", rollbackMethod = "rollback")
public boolean prepare(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "a") String a);
public boolean commit(BusinessActionContext actionContext);
public boolean rollback(BusinessActionContext actionContext);
}