SpringBoot整合Seata
# 1、每个服务建立undo表
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 COMMENT='Seata分布式事务undoLog表';
2
3
4
5
6
7
8
9
10
11
12
13
每一个微服务都必须建立回滚日志表
# 2、导入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
2
3
4
搜索seata-all,发现实际上导入的是
seata的实际版本是1.3.0
# 3、安装Seata服务器
Releases · seata/seata (github.com) (opens new window)
注意,这里下载的版本必须跟pom中引入的一样。我这里是1.3.0,那么就去下载1.3.0
# 修改registry.conf使用nacos注册中心
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "192.168.31.250:18848"
group = "DEFAULT_GROUP"
namespace = ""
cluster = "default"
username = ""
password = ""
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "192.168.31.250:18848"
namespace = ""
group = "DEFAULT_GROUP"
cluster = "default"
username = ""
password = ""
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
指定使用nacos注册中心,同时配置中心也使用nacos。
指定了配置后还需要初始化nacos中的seata配置
# 将配置导入到nacos
# nacos-config.sh脚本准备
在conf文件夹内,需要nacos-config.sh文件,这个文件1.3.0版本是没有的。
去官网把1.3.0的源码下载下来,我们可以在script/config-center中找到文件如下:
就去nacos中把nacos-config.sh导出来,放入自己的conf文件夹中
# 初始seata配置
现在操作的是刚才下载的编译后的文件,不是源码,我这里使用编译后的文件
cd conf
# 这个ip地址就是nacos中的地址
sh nacos-config.sh 192.168.31.250
2
3
返回结果:
set nacosAddr=localhost:8848
set group=SEATA_GROUP
cat: /c/Users/SaulJ/Downloads/Programs/seata/config.txt: No such file or directory
=========================================================================
Complete initialization parameters, total-count:0 , failure-count:0
=========================================================================
Init nacos config finished, please start seata-server.
2
3
4
5
6
7
可以看到,它直接去读/c/Users/SaulJ/Downloads/Programs/seata/config.txt了,这个是我现在seata的安装位置,所以我要在这里创建一个config.txt(如果是以前的版本是默认自带config.txt文件,不用自己创建。)
config.txt就是seata各种详细的配置,执行 nacos-config.sh 即可将这些配置导入到nacos,这样就不需要将file.conf和registry.conf放到我们的项目中了,需要什么配置就直接从nacos中读取。
先看一下源码:
源码的service.vgroupMapping是my_text_tx-group,我们可以修改一下
至于service.default.grouplist不用修改,因为我是准备本机启动seata,**如果将来分机启动seata,才指定ip和端口。**到时直接在自己的config.txt中配置就可以了,其他让它使用设置中心的默认配置。
config.txt配置如下:
service.vgroupMapping.seata-server-group=default
事务群组(可以每个应用独立取名,也可以使用相同的名字)
执行下面命令:
sh nacos-config.sh -h 192.168.31.250 -p 18848 -g DEFAULT_GROUP
命令解析:
-h 指定nacos的地址
-p 指定nacos的端口
-g 指定配置的分组,注意是配置的分组
-t 指定明明空间id
-u 指定nacos的用户名,如果开启了注册和配置认证才需要指定,默认是不开启的
-w 指定nacos的密码,如果开启了注册和配置认证才需要指定,默认是不开启的
2
3
4
5
6
执行结果:
我去配置中心查看,发现配置已经成功
# 启动Seata
直接启动bin中的bat文件,然后去nacos注册中心查看是是否启动成功。
# 4、使用Seata代理数据源
import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
/**
* 使用Seata代理数据源
* @author wujiajun
* @date 2021/7/22
*/
@Configuration
public class SeataConfig {
@Autowired
DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSource(DataSourceProperties dataSourceProperties) {
HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
if (StringUtils.hasText(dataSourceProperties.getName())) {
dataSource.setPoolName(dataSourceProperties.getName());
}
return new DataSourceProxy(dataSource);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 5、微服务配置yml
# seata配置
seata:
tx-service-group: seata-server-group # 事务群组(可以每个应用独立取名,也可以使用相同的名字)
service:
vgroup-mapping:
seata-server-group: default # 这个key必须和上面的tx-service-group值是一样的,value值要和seata中的配置是一样的
registry:
type: nacos
nacos:
application: seata-server
server-addr: 192.168.31.250:18848
group : DEFAULT_GROUP
namespace: ""
username: ""
password: ""
config:
type: nacos
nacos:
application: seata-server
server-addr: 192.168.31.250:18848
group: DEFAULT_GROUP
namespace: ""
username: ""
password: ""
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
这里的注意点我都注释出来了
# 6、入口方法开启分布式事务
@GlobalTransactional
# 7、每一个小事务用@Transactional(rollbackFor = Exception.class)
启动各个微服务,测试demo,已经成功了。分别开启和关闭分布式事务@GlobalTransactional,测试插入数据,发现已经成功整合Seata了。
# 后话
Seata比较适合B端增删改查的分布式事务,如果是高并发场景,特别是C端场景中,还是要使用消息中间件,手动补偿+最大努力通知,像下订单锁库存中,就不要用Seata了,毕竟Seata无论哪个模式都是有性能损耗,也只有异步消息才没有性能损耗。
反过来,如果是像多个微服务,只是B端的一些大保存方法什么的,非常适合用Seata。
Seata模式,还有Seata文件的持久化,这里就不展开说了,我都是采用默认的,至于更多可以去官网了解。
# 参考资料
seata/seata-samples: seata-samples (github.com) (opens new window)
Seata 1.4.0 + nacos配置和使用,超详细_jixieguang的博客-CSDN博客_seata1.4.0 (opens new window)