Seata控制分布式事务
1,每一个微服务先必须创建undo_log数据库表;
2,安装事务协调器
- (1), seata-server: 下载链接: Seata.,找到对应的版本
- (2),registry.conf:注册中心配置;修改registry type=nacos
- (3),file.comf
- (4),启动seata-server
3,整合
1,导入依赖:spring-cloud-starter-alibaba-seata
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.1.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
<!-- <exclusion>-->
<!-- <groupId>io.seata</groupId>-->
<!-- <artifactId>seata-spring-boot-starter</artifactId>-->
<!-- </exclusion>-->
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>0.9.0</version>
</dependency>
2,所有想要用到分布式事务的微服务使用seata DataSourceProxy代理自己的数据源
@Configuration
public class MySeataConfig {
@Autowired
DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSource(DataSourceProperties dataSourceProperties){
//properties.initializeDataSourceBuilder().type(type).build();
HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
if (StringUtils.hasText(dataSourceProperties.getName())) {
dataSource.setPoolName(dataSourceProperties.getName());
}
System.out.println(dataSource);
DataSourceProxy dataSourceProxy = new DataSourceProxy(dataSource);
return new DataSourceProxy(dataSourceProxy);
}
}
3,将redistry.conf,file.conf复制到resource路径下
修改file.conf,spring.cloud.alibaba.seata.tx-service-group=${自己微服务名字}-seata-service-group
4,启动测试分布式事务
5,给分布式大事务的入口标注@GlobalTransactional
6,每一个远程的小失误用@Taansactional
注意
1,注意依赖引入的版本,因为自带seata-all依赖,查看版本,如果不匹配,剔除,重新导入,
2,尤其注意file.conf的配置,可以根据版本去官网查看文档,这里只是记录使用,
补充
* 本地事务失效问题
* 同一个对象内事务方法互相默认失效,原因是绕过了代理对象,事务使用代理对象来控制的
* 解决:使用代理对象来调用事务方法
* 1),引入aop-starter;->spring-boot-starter-aop->引入了aspectj,aspectjweaver
* 2),@EnableAspectJAutoProxy(exposeProxy = true):开启aspectj动态代理功能,以后所有的动态代理都是aspectj创建的(即使没有接口,也可以创建动态代理),
* 不开启,使用默认jdk动态代理 exposeProxy = true对外暴露代理对象
* 3),本类互调用代理对象
* OrderServiceImpl orderService = (OrderServiceImpl) AopContext.currentProxy();
* orderService.b();
* orderService.c();