使用Seata实现分布式事务真香!

之前分享了六种分布式事务方案:

本地消息表:如何通过本地消息表实现分布式事务

最大努力通知:如何使用最大努力通知实现分布式事务?与本地消息表区别?

XA模式:用二阶段三阶段提交实现分布式事务

TCC模式:如何用TCC实现分布式事务?

RocketMQ:使用RocketMQ实现分布式事务

Saga模式:如何用saga实现分布式事务?

面对这么多的实现方式,那么有没有一个统一的方案来简化这些呢?今天我们来学习一下Seata,它如何使复杂的分布式事务管理变得简单?

Seata:分布式事务的利剑

Seata(Simple Extensible Autonomous Transaction Architecture)是阿里一个开源的分布式事务解决方案,旨在提供高性能和易用的分布式事务服务。Seata解决了微服务架构下不同服务间数据一致性的问题,让开发者能够更加专注于业务逻辑。

Seata 主要包括以下三个核心组件:

  1. Transaction Coordinator (TC):事务协调器,维护全局和分支事务的状态,驱动全局事务的提交或回滚。作为服务单独部署。
  2. Transaction Manager (TM):事务管理器,定义全局事务的范围:开始全局事务、提交或回滚全局事务。
  3. Resource Manager (RM):资源管理器,管理分支事务处理的资源,与 TC 通信以注册分支事务和报告分支事务的状态,并驱动分支事务的提交或回滚。

工作流程

  1. 开始事务:TM 请求 TC 开启一个新的全局事务。TC 生成一个全局唯一的事务ID。

  2. 业务执行:在全局事务内,微服务可以调用其他微服务。当本地事务被执行时,RM 会向 TC 注册相应的分支事务。

  3. 提交或回滚:根据业务执行的结果,TM 会通知 TC 提交或回滚全局事务。TC 则会协调所有参与当前全局事务的 RM,驱动所有分支事务的提交或回滚。

Seata 的事务模式

Seata 支持三种事务模式,以应对不同的业务场景:

1. AT 模式(自动提交模式)

AT 模式是一种无侵入式的分布式事务解决方案,主要用于简化开发者对分布式事务的处理。需要创建一个undo_log表。

  • 第一阶段:分支事务利用 RM 模块中对 JDBC 数据源代理,加入了若干流程,对业务 SQL 进行解释,把业务数据在更新前后的数据镜像组织成回滚日志,并生成 undo log 日志,对全局事务锁的检查以及分支事务的注册等,利用本地事务 ACID 特性,将业务 SQL 和 undo log 写入同一个事物中一同提交到数据库中,保证业务 SQL 必定存在相应的回滚日志,最后对分支事务状态向 TC 进行上报。这个跟MySQL的undo log是不是有点类似。

  • 第二阶段:

    • TM决议全局提交:当 TM 决议提交时,就不需要同步协调处理了,TC 会异步调度各个 RM 分支事务删除对应的 undo log 日志即可,这个步骤非常快速地可以完成。这个机制对于性能提升非常关键,我们知道正常的业务运行过程中,事务执行的成功率是非常高的,因此可以直接在本地事务中提交,这步对于提升性能非常显著。

    • TM决议全局回滚:当 TM 决议回滚时,RM 收到 TC 发送的回滚请求,RM 通过 XID 找到对应的 undo log 回滚日志,然后利用本地事务 ACID 特性,执行回滚日志完成回滚操作并删除 undo log 日志,最后向 TC 进行回滚结果上报。

2. TCC 模式(Try-Confirm-Cancel 模式)

TCC 是一种更加灵活的分布式事务处理模式,需要开发者显式地定义事务的三个阶段:Try、Confirm 和 Cancel。

  • Try 阶段:尝试执行业务操作,检查系统资源是否足够,并对必要的资源进行预留。
  • Confirm 阶段:如果 Try 阶段成功,Confirm 阶段会正式提交业务操作,利用 Try 阶段预留的资源完成实际的业务逻辑。
  • Cancel 阶段:如果业务执行失败,或者是其他业务分支失败导致需要回滚,Cancel 阶段会被触发,用于释放 Try 阶段预留的资源,并撤销执行的操作。

Seata 是怎么处理空回滚的呢?

Seata 的做法是新增一个 TCC 事务控制表,包含事务的 XID 和 BranchID 信息,在 Try 方法执行时插入一条记录,表示一阶段执行了,执行 Cancel 方法时读取这条记录,如果记录不存在,说明 Try 方法没有执行。

Seata 是怎么处理悬挂的呢?

Seata在 TCC 事务控制表记录状态的字段 status 中增加一个状态: suspended:4 当执行二阶段 Cancel 方法时,如果发现 TCC 事务控制表没有相关记录,说明二阶段 Cancel 方法优先一阶段 Try 方法执行,因此插入一条 status=4 状态的记录,当一阶段 Try 方法后面执行时,判断status=4 ,则说明有二阶段 Cancel 已执行,并返回 false 以阻止一阶段 Try 方法执行成功。

3. Saga 模式(长事务模式)

Saga 模式适用于长时间运行的业务流程,将一个大的分布式事务拆分为多个子事务,每个子事务都有其对应的补偿操作。

  • 原理:在 Saga 模式中,事务被分解为一系列的局部事务,每个局部事务都有对应的正向操作(业务逻辑)和反向操作(补偿逻辑)。正向操作用于执行业务逻辑,反向操作用于在事务执行失败时回滚已执行的操作。
  • 执行流程:正向操作按照预定的顺序执行。如果所有局部事务都成功,那么整个 Saga 事务成功。如果某个局部事务失败,之前执行的局部事务会按照相反的顺序执行其反向操作,以达到回滚的效果。

通过这三种模式,Seata 能够满足不同场景下的分布式事务管理需求,帮助开发者有效地解决分布式事务带来的挑战。

4.XA模式

XA 模式是从 1.2 版本支持的事务模式。XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准。Seata XA 模式是利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种事务模式。

在 Seata 的 XA 模式中,Seata 作为事务协调器,负责实现两阶段提交协议,管理参与分布式事务的多个资源管理器。XA的RM(资源管理器)通常是指数据库,而Seata的RM是作为客户端与AP集成在一起,AP创建RM。在第一阶段,资源管理器准备事务并锁定资源;在第二阶段,根据协调器的指令提交或回滚事务。整体流程如下:

  1. TM 向 TC 请求发起(Begin)、提交(Commit)、回滚(Rollback)全局事务。
  2. TM 把代表全局事务的 XID 绑定到分支事务上。
  3. RM 向 TC 注册,把分支事务关联到 XID 代表的全局事务中。
  4. RM 把分支事务的执行结果上报给 TC。(可选)
  5. TC 发送分支提交(Branch Commit)或分支回滚(Branch Rollback)命令给 RM。

总结

  1. 一致性保证:Seata 保证了分布式事务的强一致性,即使在复杂的分布式场景中也能确保数据的一致性。

  2. 易于集成:Seata 提供了对多种流行框架的集成能力,使得在现有微服务架构中集成 Seata 成为可能。

  3. 高可用和可扩展:Seata 设计了高可用和可扩展性,可以支持大规模的微服务架构。

在微服务架构中处理分布式事务是一个复杂的问题,但 Seata 提供了一个简单有效的解决方案。通过理解 Seata 的核心组件和工作流程,开发者可以更加自信地在自己的微服务项目中实现分布式事务管理。无论是在面试中讨论分布式事务的解决方案,还是在实际项目中实施分布式事务,Seata 都是一个值得考虑的选择。

相关推荐
技术路上的苦行僧12 分钟前
分布式专题(10)之ShardingSphere分库分表实战指南
分布式·shardingsphere·分库分表
小蜗牛慢慢爬行21 分钟前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
GitCode官方1 小时前
GitCode 光引计划投稿 | GoIoT:开源分布式物联网开发平台
分布式·开源·gitcode
wm10431 小时前
java web springboot
java·spring boot·后端
小扳3 小时前
微服务篇-深入了解 MinIO 文件服务器(你还在使用阿里云 0SS 对象存储图片服务?教你使用 MinIO 文件服务器:实现从部署到具体使用)
java·服务器·分布式·微服务·云原生·架构
龙少95433 小时前
【深入理解@EnableCaching】
java·后端·spring
溟洵5 小时前
Linux下学【MySQL】表中插入和查询的进阶操作(配实操图和SQL语句通俗易懂)
linux·运维·数据库·后端·sql·mysql
SomeB1oody7 小时前
【Rust自学】6.1. 定义枚举
开发语言·后端·rust
SomeB1oody7 小时前
【Rust自学】5.3. struct的方法(Method)
开发语言·后端·rust
啦啦右一9 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring