分布式事务seata(AT模式)
seata模式适用于一般场景,不适用于高并发场景。因为锁太多导致串行,没法并发。
①给每个微服务加一个undo_log表
– 注意此处0.3.0+ 增加唯一索引 ux_undo_log
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=1 DEFAULT CHARSET=utf8;
②参与分布式事务的微服务导包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
由springcloud控制版本
③下载一个事物协调器,即TC
https://github.com/seata/seata/releases
下载的版本号:看看maven的library里面的seata-all是什么版本就下载什么版本
④解压seata-server,配置事物协调器里面的registry.conf
我用的nacos做注册中心,所以这里的type就配nacos
registry {
#file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = “nacos”
下面的config这里用file方式,这里type就用file,即配置文件信息在file.conf中
config {
#file、nacos 、apollo、zk、consul、etcd3
type = “file”
⑤想用分布式事务的每一个微服务需要使用seata DataSourceProxy代理自己的数据源
/**
* @author Admin
* springboot 2.x的代理方法 1.x的代理方法参考官网
* 注入 DataSourceProxy
* 因为 Seata 通过代理数据源实现分支事务,如果没有注入,事务无法成功回滚
*/
@Configuration
public class MySeataConfig {
@Autowired
private DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSource(DataSourceProperties dataSourceProperties){
HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
if(!StringUtils.isBlank(dataSourceProperties.getName())){
dataSource.setPoolName(dataSourceProperties.getName());
}
return new DataSourceProxy(dataSource);
}
}
⑥把 registry.conf和file.conf复制到每一个微服务resource下面
file.conf 的 service.vgroup_mapping 配置必须和spring.application.name一致
默认会使用 ${spring.application.name}-fescar-service-group作为服务名注册到 Seata Server上,如果和file.conf中的配置不一致,会提示 no available server to connect错误
所以修改file.conf
service {
#vgroup->rgroup
vgroup_mapping.service-provider-fescar-service-group = “default”
使用分布式微服务的都要这样改
⑦ 每个存在分布式大事务的入口标注
@GlobalTransactional
每个小事务依然用
@Transactional(rollbackFor = Exception.class)