Seata原理浅析

Seata原理浅析
最新回答
落日在山时

2020-07-22 14:51:20

Seata原理浅析

Seata是阿里开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。它为用户提供了XA、AT、TCC和SAGA四种事务模式,以满足不同业务场景的需求。

一、Seata的角色

Seata中主要包含以下三种角色:

  • TC(Transaction Coordinator):事务协调者,用来协调全局和各个分支事务(不同服务)的状态,驱动它们的回滚或提交。
  • TM(Transaction Manager):事务管理者,业务层中用来开启/提交/回滚一个整体事务(在调用服务的方法中用注解开启事务)。
  • RM(Resource Manager):资源管理者,管理分支事务,与TC进行协调注册分支事务,并且汇报分支事务的状态,驱动分支事务的提交或回滚。

二、事务模式

  1. XA模式

    Seata的XA模式大体与2PC事务相似。

    流程介绍

    第一阶段:RM注册分支事务到TC;RM执行分支业务的SQL但不提交;RM报告执行状态到TC。

    第二阶段:TC检测各分支事务状态,判断整体事务提交或回滚;RM接受TC的指令,进行统一的提交或回滚操作。

    优缺点

    优点:事务强一致性,满足ACID原则;实现简单,无代码入侵。

    缺点:一阶段锁定资源,二阶段结束才释放,性能较差;依赖关系型数据库实现事务。

  2. AT模式

    AT模式(Auto Transaction)基于XA演进而来,需要数据库支持。如果是MySQL,则需要5.6以上版本才支持XA协议。

    AT模式是一种无侵入的分布式事务解决方案,用户只需关注自己的业务SQL,Seata框架会在第一阶段拦截并解析SQL,生成undo log,并自动生成事务二阶段的提交和回滚操作。

    流程介绍

    第一阶段:RM注册分支事务到TC;记录undo log(数据快照);RM执行分支业务的SQL并提交;RM报告执行状态到TC。

    第二阶段:TC检测各分支事务状态,判断整体事务提交或回滚;RM接受TC的指令,进行统一的提交或回滚操作(提交时,异步删除相应分支的undo log;回滚时,根据undo log生成补偿回滚的SQL,执行分支回滚并返回结果给TC)。

    脏写问题

    Seata通过全局锁来管理事务,持有全局锁的事务才有执行SQL的权利。这样可以避免并发事务之间的脏写问题。

    数据快照

    RM在第一阶段将分支事务注册到TC时,会在undo log保存两个数据快照,分别是before-image(数据修改前的快照)和after-image(数据修改后的快照)。当发生异常时,before-image用来做数据回滚,after-image用来判断修改后数据于当前数据是否相同,相同则通过before-image做数据回滚,不同则说明被其他非Seata事务修改过,记录异常,人工介入。

    脏读问题

    Seata默认的全局事务是读未提交。为了避免脏读现象,业务查询时要使用@GlobalTransactional或@GlobalLock来修饰查询方法的调用,并且查询语句须使用select for update语句。这样可以确保在执行SQL前会检查全局锁是否存在,只有当全局锁完成之后,才能继续执行SQL。

    优缺点

    优点:一阶段直接完成事务提交,释放数据库资源,性能比较好;利用全局锁实现读写隔离;没有代码入侵,框架自动完成回滚或提交。

    缺点:两阶段之间属于软状态,属于最终一致;数据快照会影响性能,但比XA模式要好很多。

  3. TCC模式

    TCC模式与AT模式很相似,每阶段都是独立事务,不同的是TCC通过人工编码来实现数据恢复。

    流程介绍

    TCC分为Try、Confirm和Cancel三个阶段。Try阶段进行资源的检测和预留;Confirm阶段完成资源操作业务,要求Try成功,Confirm一定能成功;Cancel阶段进行预留资源的释放,可以理解为Try的反向操作。

    空回滚和业务悬挂

    分支事务Try操作阻塞时,可能导致全局事务超时触发Cancel操作。在Try未执行时先执行了Cancel,这时的Cancel理论上不应该回滚,这时就需要空回滚。对于已经空回滚的业务,这时如果线程不再阻塞,继续执行Try,但不可能Confirm或Cancel,这就是业务悬挂。为了避免空回滚和业务悬挂,需要在执行Cancel操作时判断有没有执行Try操作,相应的,在执行Try时判断有没有该事务是否回滚过。

    优缺点

    优点:一阶段直接完成事务提交,释放数据库资源,性能比较好;相比AT,无需生成快照和使用全局锁,性能最好;不依赖数据库事务,依赖补偿操作,可用于非事务型数据库。

    缺点:代码入侵,每个阶段都需要编写对应的业务代码;软状态,属于最终一致;需要考虑Confirm和Cancel的失败情况,做好幂等处理。

  4. Saga模式

    Saga模式是Seata提供的长事务解决方案。也分为两个阶段:一阶段直接提交本地事务;二阶段成功则什么都不做,失败则通过编写补偿业务来回滚。

    优缺点

    优点:事务参与者可以基于事件驱动实现异步调用,吞吐高;一阶段直接提交本地事务,无锁,性能好;代码入侵较TCC低,实现简单。

    缺点:软状态持续时间不确定,时效性差;没有锁和事务隔离,可能会有脏写。

三、总结

Seata提供了多种事务模式以满足不同业务场景的需求。XA模式适用于一致性、隔离性要求高的业务场景;AT模式适用于继续使用关系型数据库的大多分布式事务场景;TCC模式适用于对性能要求高,且有非关系型数据库参与的事务;Saga模式适用于业务流程较长,数据时效性要求较低的场景。在选择事务模式时,需要根据具体的业务需求和性能要求来进行权衡。