1)安装
第一步:下载:https://github.com/seata/seata/releases
第二步:解压 seata-server-0.9.0
第三步:运行bin下的seata-server.bat
2)涉及到分布式事务的数据库添加表
seata需要用到额外的一张数据库表,在需要分布式事务的数据库中执行如下sql创建表即可:
-- 注意此处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;
核心在于对业务sql进行解析,转换成undolog,所以只要支持seata分布式事务的微服务数据都需要导入该表结构
搭建Seata工程
搭建好后,相似于一个jar包,可以在需要分布式事务的服务中引入依赖即可
1)第一步:创建模块并导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xxx</artifactId>
<groupId>com.xxx</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>transaction-seata</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2)第二步:创建一个自动配置类
import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
public class SeataAutoConfiguration {
/***
* 创建代理数据库
* 会将und_log绑定到本地事务中
* @param environment 环境配置
* @return 代理数据源
*
* @Primary作用:如果一个接口有多个实现类,如果没有指定用那个,那么可以使用@Primary来指定一个默认值
*/
@Primary
@Bean
public DataSourceProxy dataSource(Environment environment) {
//创建数据源对象
HikariDataSource dataSource = new HikariDataSource();
//获取数据源链接地址
dataSource.setJdbcUrl(environment.getProperty("spring.datasource.url"));
//设置数据库驱动
dataSource.setDriverClassName(environment.getProperty("spring.datasource.driver-class-name"));
//获取数据库名字
dataSource.setUsername(environment.getProperty("spring.datasource.username"));
//获取数据库密码
dataSource.setPassword(environment.getProperty("spring.datasource.password"));
//将数据库封装成一个代理数据库
return new DataSourceProxy(dataSource);
}
/***
* 全局事务扫描器
* 用来解析带有@GlobalTransactional注解的方法,然后采用AOP的机制控制事务
* @param environment 环境配置
* @return 全局事务注解扫描
*/
@Bean
public GlobalTransactionScanner globalTransactionScanner(Environment environment) {
//事务分组名称
String applicationName = environment.getProperty("spring.application.name");
String groupName = environment.getProperty("seata.group.name");
if (applicationName == null) {
return new GlobalTransactionScanner(groupName == null ? "my_test_tx_group" : groupName);
} else {
return new GlobalTransactionScanner(applicationName, groupName == null ? "my_test_tx_group" : groupName);
}
}
}
3)第三步:添加自动配置类的配置文件
这个微服务创建好后,会以jar包的方式存在每个需要用到分布式事务的微服务中,为了方便,我们需要配置自动配置类,在resource
下创建META-INF
目录,然后在该目录下创建spring.factories
文件在里面添加如下配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.leyou.seata.SeataAutoConfiguration
4)第四步:拷贝seata服务配置文件
将上图的两个文件拷贝到ly-transaction-seata
微服务的resource
目录下。
细节:
registry.conf中默认使用的是文件加载方式,所以我们不需要改:
file.conf中记录的是seata服务的地址:
在需要分布式事务的服务中引入seata服务
<!--分布式事务添加-->
<dependency>
<groupId>com.xxx</groupId>
<artifactId>transaction-seata</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在需要分布式事务的方法上[该方法中有远程调用其他服务]
@GlobalTransactional // 开启Seata分布式事务
@Transactional // 本地事务注解
public Long seataLog() {
//代码无需要改动,只需要加上seata分布式事务
}
细节:
1、由于在seata服务中的自动配置类使用了代理数据源的类,而且交给spring管理,但是在spring容器中之前已经有了一个数据源类,而且两者的名字一样,所以,我们需要在application.yml中允许替换原本就在spring容器中的数据源类,使用我们seata服务中的代理数据源类
spring:
main:
allow-bean-definition-overriding: true
2.记得mysql需要使用高驱动版本,例如8.0.X版本