Seata实现分布式事务

1,305 阅读7分钟

Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 ATTCCSAGAXA 事务模式,为用户打造一站式的分布式解决方案。

Seata中的组件角色

  • TC(事务协调者,Transaction Coordinator) :是Server端,要单独部署,维护全局和分支事务的状态,驱动全局事务提交或回滚;
  • TM(Transaction Manager) :是Client端,由业务系统集成,定义全局事务;
  • RM(Resource Manager) :是Client端,由业务系统集成,管理分支事务处理的资源。

在这里插入图片描述

Seata管理的分布式事务的典型生命周期:

  1. TM要求TC开始一项新的全局事务。TC生成代表全局事务的XID
  2. XID通过微服务的调用链传播。
  3. RM将本地事务注册为XIDTC的相应全局事务的分支。
  4. TM要求TC提交或回退相应的XID全局事务。
  5. TC驱动XID的相应全局事务下的所有分支事务以完成分支提交或回滚。

Seata的事务模式

Seata针对不同的业务场景提供了四种不同的事务模式,具体如下:

  • AT模式AT 模式的一阶段、二阶段提交和回滚(借助undo_log表来实现)均由 Seata 框架自动生成,用户只需编写“业务SQL”,便能轻松接入分布式事务,AT 模式是一种对业务无任何侵入的分布式事务解决方案。
  • TTC模式: 相对于 AT 模式,TCC 模式对业务代码有一定的侵入性,但是 TCC 模式无 AT 模式的全局行锁,TCC 性能会比 AT模式高很多。适用于核心系统等对性能有很高要求的场景。
  • SAGA模式Sage 是长事务解决方案,事务驱动,使用那种存在流程审核的业务场景,如: 金融行业,需要层层审核。
  • XA模式XA模式是分布式强一致性的解决方案,但性能低而使用较少。

AT模式

AT模式,分为两个阶段

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源
  • 二阶段:提交异步化 ( 或者事务执行失败,回滚通过一阶段的回滚日志进行反向补偿)

一阶段
在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。

在这里插入图片描述

二阶段:执行成功,进行分布式事务提交
业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。
在这里插入图片描述

二阶段:执行失败,进行业务回滚
首先对比“数据库当前业务数据”和 “after image”,避免发生业务脏写(类似于CAS操作),完成校验后用“before image”还原业务数据,并且删除中间数据。

在这里插入图片描述

TCC模式

tcc模式主要可以分为三个阶段:

  • Try:做业务检查和资源预留
  • Confirm:确认提交
  • Cancel:业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放
    在这里插入图片描述

TCC模式下常见的三种异常
1.空回滚
空回滚就是对于一个分布式事务,在没有调用 TCC 资源 Try 方法的情况下(如机器宕机、网络异常),调用了二阶段的 Cancel 方法,Cancel 方法需要识别出这是一个空回滚,然后直接返回成功。

解决方案
需要一张额外的事务控制表,其中有分布式事务 ID 和分支事务 ID,第一阶段 Try 方法里会插入一条记录,表示一阶段执行了。Cancel 接口里读取该记录,如果该记录存在,则正常回滚;如果该记录不存在,则是空回滚。

2.幂等
幂等就是对于同一个分布式事务的同一个分支事务,重复去调用该分支事务的第二阶段接口,因此,要求 TCC 的二阶段 ConfirmCancel 接口保证幂等,不会重复使用或者释放资源。如果幂等控制没有做好,很有可能导致资损等严重问题。

解决方案
记录每个分支事务的执行状态。在执行前状态,如果已执行,那就不再执行;否则,正常执行。前面在讲空回滚的时候,已经有一张事务控制表了,事务控制表的每条记录关联一个分支事务,那我们完全可以在这张事务控制表上加一个状态字段,用来记录每个分支事务的执行状态。

3.悬挂
悬挂就是对于一个分布式事务,其二阶段 Cancel 接口比 Try 接口先执行。因为允许空回滚的原因,Cancel 接口认为 Try 接口没执行,空回滚直接返回成功,对于 Seata 框架来说,认为分布式事务的二阶段接口已经执行成功,整个分布式事务就结束了。

解决方案
二阶段执行时插入一条事务控制记录,状态为已回滚,这样当一阶段执行时,先读取该记录,如果记录存在,就认为二阶段已经执行;否则二阶段没执行。

saga模式

Saga模式是SEATA提供的长事务解决方案,在Saga模式中:

  • 业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,(发生失败成功的先关联的本地事务都会被回滚,可以理解为原子性)
  • 一阶段正向服务和二阶段补偿服务都由业务开发实现。

在这里插入图片描述

目前SEATA提供的Saga模式是基于状态机引擎来实现的,机制是:

  1. 通过状态图来定义服务调用的流程并生成 json 状态语言定义文件
  2. 状态图中一个节点可以是调用一个服务,节点可以配置它的补偿节点
  3. 状态图 json 由状态机引擎驱动执行,当出现异常时状态引擎反向执行已成功节点对应的补偿节点将事务回滚
  4. 可以实现服务编排需求,支持单项选择、并发、子流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能

Seata Saga 实现了一个状态机,可以编排服务的调用流程及正向服务的补偿服务,生成一个 json 文件定义的状态图,状态机引擎驱动到这个图的运行,当发生异常的时候状态机触发回滚,逐个执行补偿服务。

同时Seata 也存在空回滚、幂等、悬挂问题。

XA模式

XA 模式是 Seata 将会开源的另一种无侵入的分布式事务解决方案:

  • 无侵入
  • 将快照数据和行锁等通过 XA 指令委托给了数据库来完成

XA模式是分布式强一致性的解决方案,但性能低而使用较少。

Seata server 的模块组成

Seata server在整个Seata中担任事务协调中的角色(即TC),维护全局和分支事务的状态,驱动全局事务提交或回滚。
具有 高可用、 高性能、高扩展性等特点。
在这里插入图片描述
Seata Server的组件构成:

  • Coordinator Core:在最下面的模块是事务协调器核心代码,主要用来处理事务协调的逻辑,如是否commit,rollback等协调活动。
  • Store:存储模块,用来将我们的数据持久化,防止重启或者宕机数据丢失。
  • Discover: 服务注册/发现模块,用于将Server地址暴露给我们Client
  • Config: 用来存储和查找我们服务端的配置。
  • Lock: 锁模块,用于给Seata提供全局锁的功能。
  • Rpc:用于和其他端通信。
  • HA-Cluster:高可用集群,目前还没开源。为Seata提供可靠的高可用功能。