Seata — 分布式事务
1. 分布式事务简介
分布式事务是指在分布式系统中,事务涉及到多个数据库和服务,需要跨多个系统节点协调完成事务的提交和回滚,保证系统的一致性。由于涉及多个节点,分布式事务比单一数据库中的事务实现更为复杂。
归其原因就是参与事务的多个子业务在不同的微服务,跨越了不同的数据库。虽然每个单独的业务都能在本地遵循ACID,但是它们互相之间没有感知,不知道有人失败了,无法保证最终结果的统一,也就无法遵循ACID的事务特性了。
这就是分布式事务问题,出现以下情况之一就可能产生分布式事务问题:
-
业务跨多个服务实现
-
业务跨多个数据源实现
2. Seata介绍
解决分布式事务的方案有很多,但实现起来都比较复杂,因此我们一般会使用开源的框架来解决分布式事务问题。在众多的开源分布式事务框架中,功能最完善、使用最多的就是阿里巴巴在2019年开源的Seata了。
官网:https://seata.apache.org/zh-cn/docs/overview/what-is-seata/
其实分布式事务产生的一个重要原因,就是参与事务的多个分支事务互相无感知,不知道彼此的执行状态。因此解决分布式事务的思想非常简单:
就是找一个统一的事务协调者,与多个分支事务通信,检测每个分支事务的执行状态,保证全局事务下的每一个分支事务同时成功或失败即可。大多数的分布式事务框架都是基于这个理论来实现的。
Seata也不例外,在Seata的事务管理中有三个重要的角色:
-
TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
-
TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
-
RM (Resource Manager) - 资源管理器:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
其中,TM和RM可以理解为Seata的客户端部分,引入到参与事务的微服务依赖中即可。将来TM和RM就会协助微服务,实现本地分支事务与TC之间交互,实现事务的提交或回滚。
而TC服务则是事务协调中心,是一个独立的微服务,需要单独部署。
3. 服务部署
Seata服务部署可以通过Docker或直接下载来实现:
-
Docker部署:使用Seata官方的Docker镜像,配置
registry.conf
和file.conf
文件,将Nacos或其他注册中心的配置写入后启动容器。通过命令docker run
或docker-compose
可以快速部署并运行Seata服务。 -
直接下载:下载Seata Server压缩包并解压,修改配置文件
registry.conf
(注册中心地址)和file.conf
(数据库存储配置),然后通过sh startup.sh
命令启动Seata Server。
可以参考官网和其他资料。
4. 微服务集成Seata
参与分布式事务的每一个微服务都需要集成Seata。
4.1 引入依赖
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
4.2 配置文件
seata: # Seata的配置块,Seata是一个分布式事务框架
registry: # 配置Seata的TC(Transaction Coordinator)服务的注册中心信息
type: nacos # 指定Seata的服务注册中心类型为Nacos(分布式服务注册发现中心)
nacos:
server-addr: 192.168.1.101:8848 # Nacos服务地址,IP和端口号,用于注册和发现Seata服务
namespace: "" # Nacos中的命名空间,空值表示使用默认命名空间
group: DEFAULT_GROUP # Nacos的服务分组,通常用来隔离不同的服务集群,默认是DEFAULT_GROUP
application: seata-server # 注册到Nacos的Seata服务名称,用于各微服务寻找TC服务
username: nacos # 访问Nacos的用户名,确保Seata有权限连接到Nacos
password: nacos # 访问Nacos的密码,与用户名配合验证访问权限
tx-service-group: cyt # 设置事务组的名称,用于标识不同的业务场景
service:
vgroup-mapping: # 配置虚拟事务组到实际TC集群的映射关系
hmall: "default" # 将事务组"hmall"映射到TC集群"default",即指定该事务组的事务协调器
4.3 开启分布式事务
使用 @GlobalTransactional 注解开启分布式事务:
将以前的的@Transactional
注解改为Seata提供的@GlobalTransactional。
@GlobalTransactional
注解就是在标记事务的起点,将来TM就会基于这个方法判断全局事务范围,初始化全局事务。
5. 总结
Seata服务部署后,在微服务中引入Seata依赖并完成配置后,通过@GlobalTransactional
注解即可开启分布式事务。关键步骤如下:
-
引入Seata依赖:在每个需要分布式事务管理的微服务中,引入Seata的相关依赖(例如
seata-spring-boot-starter
),这样就可以在Spring Boot项目中使用Seata的注解。 -
配置Seata:配置
application.yml
或application.properties
,指定Seata的事务组名称(即tx-service-group
)以及注册中心(例如Nacos)的地址等信息,以便微服务可以与Seata Server通信。 -
使用
@GlobalTransactional
注解:在需要分布式事务管理的方法上,添加@GlobalTransactional
注解,Seata会自动管理该方法调用链上的事务,确保整个调用链上的操作要么全部成功,要么全部回滚。