官网:https://seata.io/zh-cn/
官方案例地址:https://github.com/seata/seata-samples
本文采用的是seata1.0,需要注意版本的对应关系,否则会有各种奇奇怪怪的问题。
本文主要讲解如何使用seata处理分布式事务,相关原理可以直接前往官网查看,采用的是一种变相的2PC模型。
1. 环境准备相关软件:
- nacos
- seata
- mysql
- …
数据库:除了创建相关业务表外,需要创建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;2. Seata分布式事务
项目整体结构如上图,可自行创建相关工程。项目地址会在文末给出。
该工程主要分三个模块:订单、账户以及库存。在订单模块中创建订单的同时,需要扣减账户的余额以及相应商品的库存。
2.1 Seata安装可以直接采用docker进行安装:
docker run --name seata-server -p 8091:8091 -d seataio/seata-server:1.0.02.2 工程搭建
分布式事务配置过程整体可以按照如下步骤操作:(基本的增删改查就不过多阐述…)
1:需要执行分布式事务的工程中引入依赖包spring-cloud-starter-alibaba-seata 2:配置代理数据源DataSourceProxy 3:将MyBatisPlus数据源切换成代理数据源 4:指定seata-server配置 a.导入file.conf b.导入register.conf 5:配置工程中的分布式事务组 6:开始执行分布式事务的方法上添加注解@GlobalTransactional
以下步骤在三个工程中都需要。
-
引入seata 依赖
com.alibaba.cloud spring-cloud-starter-alibaba-seata 2.1.0.RELEASE -
配置代理数据源
@Configuration public class SeataDataSourceProxy { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource druidDataSource() { return new DruidDataSource(); } @Bean public DataSourceProxy dataSourceProxy(DataSource druidDataSource) { return new DataSourceProxy(druidDataSource); } @Bean @ConfigurationProperties(prefix = "mybatis") public MybatisSqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSourceProxy) { // 这里用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否则 MyBatisPlus 不会生效 MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); mybatisSqlSessionFactoryBean.setDataSource(dataSourceProxy); return mybatisSqlSessionFactoryBean; } } -
导入配置文件
将seata的相关配置文件放入工程的resource文件夹中,并且在yml中进行相关配置:
alibaba: seata: tx-service-group: demo # 这个名字要对应配置文件中的名字文件参考如下:这边采用的是最简单的file类型导入,在生产环境中应该将相关配置存储在nacos中。
file.conf
service { #vgroup->rgroup vgroup_mapping.demo = "default" #only support single node default.grouplist = "localhost:8091" #degrade current not support enableDegrade = false #disable disable = false }registry.conf
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "file" file { name = "file.conf" } } config { # file、nacos 、apollo、zk、consul、etcd3、springCloudConfig type = "file" file { name = "file.conf" } } -
添加 @GlobalTransactional 注解开启分布式事务
这个注解需要添加在业务逻辑的入口处。
比如我们的工程是创建订单的同时对账户及库存进行操作,所以直接在create方法处添加即可。
@GlobalTransactional
工程搭建完成后,我们可以进行相关测试。
首先访问localhost:2001/order/create接口创建订单,可以在数据库中看到数据正常变化。
然后再创建订单的业务过程中主动制造错误,会发现数据库中的数据未发生变化,具体可以自行测试。
3.项目地址seata-demo



