1.在数据库中新增日志回滚表 undo_log
哪个业务使用Seata的AT模式,就必须在该业务操作的数据库中添加这张表
CREATE TABLE IFNOT 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 =utf8 COMMENT ='AT transaction mode undo table';
2.添加依赖
<!-- seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<version>2.2.0.RELEASE</version>
<!--版本过低,排除后手动引入新版本-->
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.0-native-rc2</version>
</dependency>
3.在该业务的配置文件中加入以下配置:
数据库与Nacos配置略
#Seata分布式事务
seata:
enabled: true
#Seata 事务组编号,用于TC集群
#要和 service.vgroupMapping.my_tx_group=default 中配置的相同
tx-service-group: my_tx_group
## 关闭自动代理
enable-auto-data-source-proxy: false
config: #配置中心,从nacos获取配置
type: nacos
nacos:
server-addr: 127.0.0.1:8848 #nacos地址
group: SEATA_GROUP
data-id: seataServer.properties
registry: #TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
type: nacos #注册中心类型 nacos
nacos:
application: seata-server #seata服务名称
server-addr: 127.0.0.1:8848 #nacos地址
group: SEATA_GROUP #seata组,与seata所在组保持一致
4.配置DataSource
使用Seata的微服务都需要配置,作用:RM拦截业务SQL,根据where条件查询原始数据,形成快照。
@Configuration
public class DataSourceConfig {
@Autowired
private DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSourceProxy(){
HikariDataSource hikariDataSource=new HikariDataSource();
hikariDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
hikariDataSource.setJdbcUrl(dataSourceProperties.getUrl());
hikariDataSource.setUsername(dataSourceProperties.getUsername());
hikariDataSource.setPassword(dataSourceProperties.getPassword());
return new DataSourceProxy(hikariDataSource);
}
}
5.测试
在入口服务上的业务方法添加@GlobalTransactional标签
//consumer服务的test方法,调用了producer服务的test方法
@GetMapping
@GlobalTransactional(rollbackFor = Exception.class)
public String test(){
//consumer服务添加一条记录
userMapper.add("consumer");
//调用producer服务添加执行另一条sql语句
producerApi.test();
return "test is running...";
}
-------------------------------
//producer服务的test方法
@GetMapping("/transTest")
@Transactional
public String test(){
userMapper.add("producer");
int i = 1/0;
return "成功";
}
无论在consumer还是producer中只要出现了异常,数据库操作都会被回滚