Seata是一个款开源的分布式解决方案,提供了AT,TCC,Saga和XA的事务模式。

本文中我们简单介绍下主流的AT和TCC。

AT模式

AT模式是Seata主推的无侵入式解决方案,它是基于XA 2PC演进而来的一种方案,同样分为RM,TM,AP三个角色。

在AT模式下,用户只需要关心自己的业务SQL即可,Seata框架会自动生成事务和回滚操作。

下面我们看下AT事务的处理流程:

一阶段

事务第一阶段seata进行的工作如下:

  1. 解析业务SQL,找到业务SQL要执行的数据。
  2. 保存找到的数据,生成”before image”。
  3. 执行业务SQL,并通过主键获取到执行后的数据。
  4. 保存执行后的数据,生成“after image”。
  5. 插入回滚日志,写入到UNDO_LOG表中。
  6. 根据XID在TM中申请对应主键的全局行锁。
  7. 提交本地事务。
  8. 将本地事务结果上报TM。

以上几点操作均在一个数据库事务中完成,保证了一阶段的原子性。

https://kswapd.cn/seata_at1/

关于全局锁:

  1. 全局锁由TM提供用来维护事务中的一致性问题,在每次提交本地事务前都需要从TM中获取全局锁。
  2. 如果无法获取全局锁,则不能提交本地事务。
  3. 获取全局锁的尝试被限制在一定范围,如果一直无法获取,会回滚本地事务。
  4. 全局锁只锁定对应主键的行,在一阶段被获取,在二阶段被释放。

二阶段

二阶段分为提交回滚两个操作。

二阶段提交

提交操作比较简单。seata直接删除before image,after image和行锁即可。

https://kswapd.cn/seata_at_2/

二阶段回滚

回滚比较复杂,seata会回滚已经执行的业务sql,还原业务数据。

回滚步骤如下:

  1. 校验脏写,当前业务数据是否与after image一致,如果不一致终止回滚流程。
  2. 没有脏写的话,执行逆向sql,使用before image数据进行还原。
  3. 删除before image,after image, 行锁。
https://kswapd.cn/seata_at3/

TCC模式

TCC模式用户根据自己的业务场景实现Try-Confirm-Cancel三个操作来实现分布式事务,对业务代码有一定的侵入性。

三个方法分别为:

  • Try: 资源检测和预留。
  • Confirm:确认事务提交,处理预留资源。
  • Cancel:补偿操作,撤销已经预留的资源。
https://kswapd.cn/seata_tcc1/

允许空回滚

Cancel接口设计时需要支持空回滚,因为很有可能Try接口因为丢包没有收到,事务管理器会触发回滚。

image

而这个时候Cancel接口并没有真实的数据可以供回滚,但是也必须要返回成功。

防悬挂控制

这里的悬挂是指,Cancel比Try方法先执行。
主要原因是Try操作网络请求滞后,在TM发送Cancel后,业务方才收到Try请求。

所以在实现Try方法时,需要判断这个XID是否已经回滚,如果已经回滚那么不进行Try操作。

image

幂等性保证

幂等性的意思是:对同一个系统,使用同样的条件,一次请求和重复的多次请求对系统资源的影响是一致的。因为网络抖动或拥堵可能会超时,事务管理器会对资源进行重试操作,所以很可能一个业务操作会被重复调用,为了不因为重复调用而多次占用资源,需要对服务设计时进行幂等控制,通常我们可以用事务 xid 或业务主键判重来控制。

image

发表评论

邮箱地址不会被公开。 必填项已用*标注