文章目录
分布式事务介绍
分布式事务是指参与事务的各组件(包括参与者、事务服务器、资源服务器和事务管理器)分布在分布式系统的不同节点上。
简而言之,分布式事务是将一个复杂操作拆分为多个子操作,这些子操作分布在不同的服务器上且属于不同的应用系统。分布式事务的核心要求是确保这些子操作要么全部成功执行,要么全部回滚。
从本质上来看,分布式事务旨在维护跨数据库的数据一致性。
Seata介绍
Seata(Simple Extensible Autonomous Transaction Architecture)是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 通过 AT(自动补偿)、TCC(Try-Confirm-Cancel)、SAGA 和 XA 模式支持多种分布式事务场景,适用于微服务架构下的数据一致性需求。
Seata 核心组件
- TC(Transaction Coordinator):事务协调器,负责全局事务的提交或回滚。
- TM(Transaction Manager):事务管理器,定义全局事务的边界并发起全局提交或回滚。
- RM(Resource Manager):资源管理器,管理分支事务的资源,与 TC 交互以注册分支事务和报告状态。
Seata 事务模式
AT 模式(自动补偿): 通过解析 SQL 生成前后镜像,实现自动回滚。适用于大多数业务场景,对代码侵入性低。
TCC 模式(Try-Confirm-Cancel): 需要业务实现 Try、Confirm、Cancel 接口,适用于需要高一致性的场景(如资金交易)。
SAGA 模式: 长事务解决方案,通过状态机驱动异步调用,适用于业务流程复杂且耗时的场景。
XA 模式: 基于数据库 XA 协议的两阶段提交,适用于支持 XA 协议的数据库(如 MySQL、Oracle)。
Seata 工作流程
- TM 向 TC 发起全局事务,生成全局唯一 XID。
- XID 通过微服务调用传递到各分支事务。
- RM 向 TC 注册分支事务,并将其纳入全局事务管理。
- TC 根据全局事务状态决定提交或回滚所有分支事务。
seata的使用
修改配置文件
进入conf目录, 找到registry.conf
powershell
registry {
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
}
config {
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
}
支持多种方式,这里使用的nacos,其他的方式可以删除掉。
修改nacos-config.txt
service.vgroup_mapping.service-order=default
service.vgroup_mapping.service-product=default
service.vgroup_mapping.service-user=default
初始化seata到nacos的配置
在 config 目录, 执行如下命令:
cd conf
nacos-config.sh 127.0.0.1
注意: 运行命令前需要保证nacos在运行状态。
在nacos配置列表查看是否有seata的配置

看到如上图所示,说明seata初始化到nacos配置成功。
启动seata服务
执行 cd bin
seata-server.bat -p 9000 -m file
启动后在 Nacos 的服务列表下面可以看到一个名为 serverAddr 的服务。

使用seata实现事务控制
需要数据库中添加一张undo_log表.
Seata 中的 undo_log 表是AT 模式(Seata 核心事务模式)实现分布式事务回滚的核心依赖,其核心作用是记录事务执行过程中数据的修改前 / 后镜像,当分布式事务需要回滚时,通过该表的日志信息将数据恢复到事务执行前的状态,保证分布式事务的原子性。
两个阶段:
AT 模式是基于「两阶段提交」的无侵入式分布式事务方案,undo_log 是 AT 模式实现第二阶段回滚的关键:
第一阶段(业务执行):执行业务 SQL 时,Seata 会拦截 SQL,记录数据的「前镜像」(修改前数据)和「后镜像」(修改后数据),并将这些信息写入 undo_log 表,同时锁定相关数据行;
第二阶段(提交 / 回滚):
若事务全局提交:删除 undo_log 中该事务的日志,释放锁;
若事务全局回滚:根据 undo_log 中的镜像数据,生成反向 SQL(如 UPDATE/DELETE/INSERT 的逆向操作),将数据恢复到修改前状态,完成后删除 undo_log 日志。
undo_log表结构:
sql
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;
项目中关于seata的配置
在需要进行分布式控制的微服务中进行下面几项配置:
- 添加 依赖:
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 数据源代理配置
Seata 是通过代理数据源实现事务分支的,所以需要配置 io.seata.rm.datasource.DataSourceProxy 的
Bean,且是 @Primary默认的数据源,否则事务不会回滚,无法实现分布式事务
java
@Configuration
public class DataSourceProxyConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
@Primary
@Bean
public DataSourceProxy dataSource(DruidDataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
}
- 在yml配置文件中添加配置
yaml
spring:
application:
name: service-order
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
shared-dataids: all-service.yaml # 配置要引入的配置
refreshable-dataids: all-service.yaml # 配置要实现动态配置刷新的配置
namespace: public
group: SEATA_GROUP
alibaba:
seata:
tx-service-group: ${spring.application.name}
profiles:
active: dev
- 在resources下添加Seata的配置文件 registry.conf
bash
registry {
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
}
config {
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
}
- 在 调用方法上开启全局事务控制
添加全局事务注解 @GlobalTransactional//全局事务控制