2020-07-22 14:51:20
Seata原理浅析
Seata是阿里开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。它为用户提供了XA、AT、TCC和SAGA四种事务模式,以满足不同业务场景的需求。
一、Seata的角色
Seata中主要包含以下三种角色:
二、事务模式
XA模式
Seata的XA模式大体与2PC事务相似。
流程介绍:
第一阶段:RM注册分支事务到TC;RM执行分支业务的SQL但不提交;RM报告执行状态到TC。
第二阶段:TC检测各分支事务状态,判断整体事务提交或回滚;RM接受TC的指令,进行统一的提交或回滚操作。
优缺点:
优点:事务强一致性,满足ACID原则;实现简单,无代码入侵。
缺点:一阶段锁定资源,二阶段结束才释放,性能较差;依赖关系型数据库实现事务。
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模式要好很多。
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的失败情况,做好幂等处理。
Saga模式
Saga模式是Seata提供的长事务解决方案。也分为两个阶段:一阶段直接提交本地事务;二阶段成功则什么都不做,失败则通过编写补偿业务来回滚。
优缺点:
优点:事务参与者可以基于事件驱动实现异步调用,吞吐高;一阶段直接提交本地事务,无锁,性能好;代码入侵较TCC低,实现简单。
缺点:软状态持续时间不确定,时效性差;没有锁和事务隔离,可能会有脏写。
三、总结
Seata提供了多种事务模式以满足不同业务场景的需求。XA模式适用于一致性、隔离性要求高的业务场景;AT模式适用于继续使用关系型数据库的大多分布式事务场景;TCC模式适用于对性能要求高,且有非关系型数据库参与的事务;Saga模式适用于业务流程较长,数据时效性要求较低的场景。在选择事务模式时,需要根据具体的业务需求和性能要求来进行权衡。