分布式事务-06-AT

AT模式是Seata最主推的分布式事务且基于XA演进而来的解决方案,是一种改进的二阶段提交,主要有三个角色:TM、RM和TC,其中TM和RM作为Seata的客户端和业务集成,TC作为Seata服务器独立部署

在AT模式下,数据库资源被当做RM,访问RM时,Seata会对请求进行拦截;每个本地事务提交时,RM会向TC(Transaction Coordinator,事务协调器)注册一个分支事务,用户只需关注自己的 业务SQL ,用户的 业务SQL 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作

流程

第一阶段

img
  1. 当访问 RM 的时候,会拦截解析 SQL 语句,保存 “before image”
  2. 执行 SQL 更新业务数据
  3. 接着保存操作后的 “after image”
  4. 插入回滚日志 undo_log
  5. 向TC注册分支事务,申请全局锁,并将其纳入到该XID对应的全局事务范围。
  6. 提交本地事务
  7. 向 TC 汇报本地事务结果

第二阶段

事务提交

如果在第一阶段所有的分支事务已经提交,则TC决定全局事务提交,此时只需要清理UNDO_LOG日志即可,相比较XA模式,不需要TC触发所有分支事务的提交

img

具体的流程为:

  1. 分支事务收到TC的提交请求之后放入异步队列中,马上返回提交成功的结果

    这里不需要同步返回的原因是:TC不需要知道分支事务的结果,因为仅仅只是一步删除UNDO_LOG记录的操作,即使不成功也不会结果造成影响,所以采用异步是有效的方式

  2. 从异步队列中执行分支提交请求,清理undo_log日志,这里并不需要分支事务的提交了,因为第一阶段中已经提交过了

理解起来就是:AT模式下的全局事务的提交只需要清理UNDO_LOG记录就行,不需要管分支(本地)事务的提交结果!

事务回滚

在第一阶段的分支事务中任何一个分支事务执行失败,都会进入全局事务回滚流程,回滚主要是依赖UNDO_LOG中的记录进行补偿的

img

具体的流程如下:

接收到TC的回滚请求后,开启本地事务用来执行回滚操作

  1. 本地事务分支开始进行对查找UNDO_LOG记录,通过XID+branch ID查到UNDO_LOG记录;

  2. 数据校验(对比更新后镜像数据与当前数据),拿到rollback_forafterImage镜像数据与当前业务表中数据比较,不同的话,比如afterImage镜像数据拿出的amount理论上为99,但是实际上amount=98,则说明已经被当前全局事务外的某个操作做了修改(实际上由于全局锁的存在,并不会存在其他全局事务对业务数据进行更新),那么事务不进行回滚。

  3. 第二步中对比结果是相等的话,就采用beforeImage和SQL的相关信息进行回滚,即

    1
    UPDATE rep SET acoumt=100 WHERE id=1
  4. 删除UNDO_LOG记录

  5. 提交本地事务

  6. 将本地事务的回滚执行结果报告给TC

隔离性保证

在AT模式下,多个全局事务操作同一张表时,它的事务隔离性保证是基于全局锁来实现的

  1. 写隔离,在第一阶段本地事务提交之前,必须确保拿到全局锁,如果拿不到全局锁则一直等待尝试,超出最大尝试次数则放弃全局锁的获取,并回滚释放本地锁(在本地事务开始之前就获到本地锁,这里的本地锁概念是数据库锁,比如对某行记录的行锁)

  2. 读隔离,Seata AT事务模式的默认全局隔离级别是Read Uncommit,在这种隔离级别下,所有事务都可以看到其它未提交事物的执行结果产生脏读,这在最终一致性的事务模型是被允许的,并且大部分是分布式事务是接受脏读的。

总结

img

优点:

  1. 原子性,AT协议保证了分布式事务的原子性,要么所有 RM 都成功提交事务,要么所有 RM 都回滚事务。
  2. 数据一致性,AT协议确保了分布式事务的一致性,所有 RM 在提交阶段只有在所有其他 RM 也准备好提交时才会提交事务。
  3. 灵活性,AT协议可以适应各种分布式环境和参与者的异构性,因为它没有对具体的数据库或资源管理器实施特定要求。

缺点:

  1. 同步阻塞,AT协议在准备和提交阶段都需要等待 RM 的响应,因此可能会引入同步阻塞,影响事务的性能和吞吐量。
  2. 单点故障,在AT协议中,TC 是关键的中心节点,如果 TC 发生故障,整个分布式事务的执行将受到影响。
  3. 数据不一致风险,在AT协议中,即使在准备阶段所有参与者都准备就绪,但在提交阶段仍然存在参与者无法提交成功的情况,这可能导致数据的不一致。

参考文档

  1. https://seata.io/zh-cn/blog/seata-at-tcc-saga.html
  2. https://www.cnblogs.com/jian0110/p/14925087.html
  3. https://zhuanlan.zhihu.com/p/78599954