Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
Seata中的组件角色
TC(事务协调者,Transaction Coordinator):是 Server端,要单独部署,维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM(Transaction Manager)和RM(Resource Manager) :是Client端,由业务系统集成。TM:定义全局事务,RM 管理分支事务处理的资源。
Seata管理的分布式事务的典型生命周期
Seata针对不同的业务场景提供了四种不同的事务模式,具体如下
AT模式,分为两个阶段
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源
二阶段:提交异步化 ( 或者事务执行失败,回滚通过一阶段的回滚日志进行反向补偿)
一阶段
在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
二阶段:执行成功,进行分布式事务提交
业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。
二阶段:执行失败,进行业务回滚
首先对比“数据库当前业务数据”和 “after image”,避免发生业务脏写(类似于CAS操作),完成校验后用“before image”还原业务数据,并且删除中间数据。
tcc模式主要可以分为三个阶段:
TCC模式下常见的三种异常
1.空回滚
空回滚就是对于一个分布式事务,在没有调用 TCC 资源 Try 方法的情况下(如机器宕机、网络异常),调用了二阶段的 Cancel 方法,Cancel 方法需要识别出这是一个空回滚,然后直接返回成功。
解决方案
需要一张额外的事务控制表,其中有分布式事务 ID 和分支事务 ID,第一阶段 Try 方法里会插入一条记录,表示一阶段执行了。Cancel 接口里读取该记录,如果该记录存在,则正常回滚;如果该记录不存在,则是空回滚。
2.幂等
幂等就是对于同一个分布式事务的同一个分支事务,重复去调用该分支事务的第二阶段接口,因此,要求 TCC 的二阶段 Confirm 和 Cancel 接口保证幂等,不会重复使用或者释放资源。如果幂等控制没有做好,很有可能导致资损等严重问题。
解决方案
记录每个分支事务的执行状态。在执行前状态,如果已执行,那就不再执行;否则,正常执行。前面在讲空回滚的时候,已经有一张事务控制表了,事务控制表的每条记录关联一个分支事务,那我们完全可以在这张事务控制表上加一个状态字段,用来记录每个分支事务的执行状态。
3.悬挂
悬挂就是对于一个分布式事务,其二阶段 Cancel 接口比 Try 接口先执行。因为允许空回滚的原因,Cancel 接口认为 Try 接口没执行,空回滚直接返回成功,对于 Seata 框架来说,认为分布式事务的二阶段接口已经执行成功,整个分布式事务就结束了。
解决方案
二阶段执行时插入一条事务控制记录,状态为已回滚,这样当一阶段执行时,先读取该记录,如果记录存在,就认为二阶段已经执行;否则二阶段没执行。
Saga模式是SEATA提供的长事务解决方案,在Saga模式中:
业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,(发生失败成功的先关联的本地事务都会被回滚,可以理解为原子性)
一阶段正向服务和二阶段补偿服务都由业务开发实现。
目前SEATA提供的Saga模式是基于状态机引擎来实现的,机制是:
Seata Saga 实现了一个状态机,可以编排服务的调用流程及正向服务的补偿服务,生成一个 json 文件定义的状态图,状态机引擎驱动到这个图的运行,当发生异常的时候状态机触发回滚,逐个执行补偿服务
同时Seata 也存在空回滚、幂等、悬挂问题。
XA 模式是 Seata 将会开源的另一种无侵入的分布式事务解决方案
XA模式是分布式强一致性的解决方案,但性能低而使用较少。
Seata server在整个Seata中担任事务协调中的角色(即TC),维护全局和分支事务的状态,驱动全局事务提交或回滚。
具有 高可用、 高性能、高扩展性等特点。