微服务-分布式事务

分布式事务

Seata

Apache Seata(incubating) 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

解决分布式事务,各个子事务之间必须能够感知到彼此的事务状态,才能保证一致

Seata事务中有三个重要的角色

  • TC(Transaction Coordinator)-事务协调者:维护全局和分支的事务状态,协调全局事务提交或回滚
  • TM(Transaction Manager)-事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务
  • RM(Resource Manager)-资源管理器:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态

部署TC服务

Seata支持多钟存储模式,但考虑到数据持久话的需要,我们一般选择基于数据库存储

这里seata的搭建需要大量的配置,他本质上是一个springboot的服务,通过application或者nacos进行配置都可。其中,数据持久化也可以选择基于Redis或者MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
services:
seata:
image: seataio/seata-server:1.5.2
container_name: seata
ports:
- "8099:8099"
- "7099:7099"
volumes:
- ./seata:/seata-server/resources
privileged: true
restart: no
networks:
- my_app_network

networks: # <-- 定义网络
my_app_network:
external: true # 告诉 Docker Compose 这个网络已经存在,不要尝试创建它


微服务中集成Seata

在微服务中引入Seata依赖

1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

在微服务中配置TC地址,在这里,Seata可能会被配置成集群注册到Nacos中,所以让微服务通过Nacos来获取TC服务的地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
seata:
registry:
type: nacos
nacos:
server-addr: localhost:8848
namespace: ""
group: DEFAULT_GROUP
application: seata-server
username: nacos
password: nacos
tx-service-group: hmall # 事务组名称
service:
vgroup-mapping: # 事务组和tc集群的映射关系
hmall: "default"

这里的配置文件可以抽出来在Nacos做共享配置文件


XA模式

事务具有强一致性,所有的分支事务仅执行不提交,等所有的分支事务执行完成后一起提交

常用数据库都支持,实现简单,并且没有代码侵入

性能恩差,依赖关系行数据库实现事务

开启方法

在配置文件中开启XA

1
2
seata:
data-source-proxy-mode: XA

在事务的入口方法处添加@GlobalTransactional注解

1
2
3
4
@Override
@GlobalTransactional
public Long createOrder(OrderFormDTO orderFormDTO) {
}

分支事务也要加上@Transactional注解以便回滚


AT模式

Seata主推的是AT模式,AT模式同样是分阶段提交的事务模型,不过弥补了XA模型中资源锁定周期过长的缺陷

XA模式是直接上一把物理排他锁,在事务过程中,任何请求都阻塞(包括读写)

AT模式是分支事务上物理锁,释放的很快,全局事务上一把逻辑锁(全局写锁)

虽然其他写的请求无法正常执行,但不影响读的请求

这也意味着在事务执行期间,AT模式会出现“脏读”问题,但最终一致性可以得到保障

开启AT模式

AT模式需要为每一个微服务提供undo_log表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 注意此处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;

在配置文件中开启AT,但这个属性的默认值就是AT(约定大于配置)

1
2
seata:
data-source-proxy-mode: AT

同XA模式,在事务的入口方法处添加@GlobalTransactional注解

分支事务也要加上@Transactional注解以便回滚



微服务-分布式事务
http://blog.170827.xyz/2025/06/23/微服务-分布式事务/
作者
XIAOBAI
发布于
2025年6月23日
许可协议