Seata原理浅析

seata · 浏览次数 : 4

小编点评

**Seata 事务模式** **1. XA 模式** * 与 2PC 事务相似,但仅在事务提交之前进行检查。 * 优点:事务强一致性、简单易用。 * 缺点:一阶段之间属于软状态,可能出现脏写。 **2. TCC 模式** * 每个阶段都是独立事务,通过事件驱动实现异步调用。 * 优点:性能好、代码入侵较低。 * 缺点:软状态、事务隔离缺失。 **3. Saga 模式** * 结合 XA 和 TCC 的优点,提供长事务解决方案。 * 优点:事务参与者可以基于事件驱动实现异步调用,吞吐高。 * 缺点:软状态持续时间不确定,时效性差。 **代码实现** * 在每个模式都需要准备工作,如导入 Seata 数据库等。 * 在执行事务时,选择合适的模式进行处理。 **性能比较** | 模式 | 性能 | 隔离性 | |---|---|---| | XA | 较低 | 高 | | TCC | 中等 | 中低 | | Saga | 较高 | 低 | **场景选择** * 性能要求高,且有非关系型数据库参与的事务。 * 业务流程较长,数据时效性要求较低的场景。

正文

前言

Seata是阿里开源的分布式事务解决方案,本文将详细介绍 Seata 的事务模式、原理以及使用。了解之前需清楚什么是分布式事务


一、什么是 Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了XA、AT、TCC 和 SAGA 事务模式,为用户打造一站式的分布式解决方案。

Seata 的几种角色:

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

简单流程图:

image.png

二、事务模式

1. XA 模式

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

1.1 流程介绍

image.png

第一阶段:

  1. RM 注册分支事务到 TC;
  2. RM 执行分支业务的 SQL 但不提交
  3. RM 报告执行状态到 TC;

第二阶段:

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

1.2 XA 优缺点

优点:

  1. 事务强一致性,满足 ACID 原则;
  2. 实现简单,无代码入侵。

缺点:

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

2. AT 模式

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

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

AT 模式下,是利用快照实现数据回滚,属于弱一致。

2.1 流程介绍

image.png

第一阶段:

  1. RM 注册分支事务到 TC;
  2. 记录 undo log(数据快照);
  3. RM 执行分支业务的 SQL 并提交
  4. RM 报告执行状态到 TC;

第二阶段:

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

例如,一个分支业务需要对account余额表中的money进行扣减 10 元,则需要进行如下流程:

image.png

2.2 脏写问题

如下图所示,并发事务之间,可能会产生脏写导致数据修改被覆盖。

image.png

如何解决脏写,Seata 通过全局锁来管理事务,持有全局锁的事务才有执行 SQL 的权利,这里全局锁只针对交由 Seata 管理的事务

如下图,简单流程大致如下:

  1. 一阶段本地事务提交前,需要确保先拿到全局锁 ;
  2. 拿不到全局锁 ,不能提交本地事务。
  3. 拿不到全局锁会重试,次数有限,超出限制将放弃,并回滚本地事务,释放本地锁。

image.png

2.3 数据快照

那么非 Seata 事务于 Seata 事务并发修改数据时如何处理?

RM 在第一阶段将分支事务注册到 TC 时,会在 undo log 保存两个数据快照,分别是:

  • before-image:数据修改前的快照
  • after-image:数据修改后的快照

当发生异常时,before-image用来做数据回滚,after-image来判断修改后数据于当前数据是否相同,相同则通过before-image做数据回滚,不同则说明被其他非 Seata 事务修改过,记录异常,人工介入。

具体流程见下图。

image.png

2.4 脏读问题

与脏写类似,是指在全局事务未提交前,被其它业务读到已提交的分支事务的数据,本质上 Seata 默认的全局事务是读未提交

那么怎么避免脏读现象呢?

  1. 业务查询时要使用@GlobalTransactional@GlobalLock来修饰查询方法的调用;
  2. 查询语句须使用select for update语句。

这样在执行 SQL 前会检查全局锁是否存在,只有当全局锁完成之后,才能继续执行 SQL,这样就防止了脏读。

不过,AT 事务模式下读已提交的成本很高,对于非必要场景还是要尽量避免使用。

传统的读已提交不需要本地锁,但这里却需要select for update语句,查询多出了加锁和竞争的开销,另外还要持锁调用 TC 的lockQuery接口以判断全局锁情况。

2.5 AT 优缺点

优点:

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

缺点:

  1. 两阶段之间属于软状态,属于最终一直;
  2. 数据快照会影响性能,但比 XA 模式要好很多;

3. TCC 模式

关于什么是 TCC 模式及原理,详情见什么是分布式事务

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

3.1 流程介绍

image.png

TCC 每个阶段是做什么的:

  1. Try:资源的检测和预留;
  2. Confirm:完成资源操作业务,要求Try成功,Confirm一定能成功;
  3. Cancel:预留资源释放,可以理解为Try的反向操作。

TCC 不存在资源阻塞的问题,因为每个方法都直接进行事务的提交,一旦出现异常通过则Cancel来进行回滚补偿,这也就是常说的补偿性事务

举例,一个扣减用户愈合的业务,假设账户 A 原来的余额是 100,需要扣减 30 元。

image.png

空回滚和业务悬挂

什么是空回滚?

分支事务Try操作阻塞时,可能导致全局事务超时触发Cancel操作。在Try未执行时先执行了Cancel,这时的Cancel理论上不应该回滚,这时就需要空回滚

image.png

什么是业务悬挂?

对于已经空回滚的业务,这时如果线程不再阻塞,继续执行Try,但不可能ConfirmCancel,这就是业务悬挂,需要避免空回滚后的Try操作。

如何解决空回滚和业务悬挂?

回滚时需要在执行Cancel操作时,判断有没有执行Try操作。相应的,在执行Try时判断有没有该事务是否回滚过。

这里,我们假设需要在冻结金额的时候进行事务操作。为了实现空回滚,防止业务悬挂,以及幂等性要求。我们必须在数据库记录冻结金额的同时,记录当前事务 ID 和执行状态,冻结金额表如下设计:

CREATE TABLE 'account_freeze_tbl'(
  'xid' varchar (128) NOT NULL,
  'user_id' varchar(255) DEFAULT NULL COMMENT '用户id',
  'freeze_money' int(11) unsigned DEFAULT '0' COMMENT '冻结金额',
  'state' int(1) DEFAULT NULL COMMENT '事务状态, O:try, 1:confirm, 2:cancel',
  PRIMARY KEY ('xid') USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

表字段设计完成后,执行如下的业务逻辑即可避免空回滚和业务悬挂。

image.png

3.2 TCC 优缺点

优点:

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

缺点:

  1. 代码入侵,每个阶段都需要编写对应的业务代码;
  2. 软状态,属于最终一致;
  3. 需要考虑ConfirmCancel的失败情况,做好幂等处理。

4. Saga 模式

关于什么是 Saga 模式及原理,详情见什么是分布式事务

Saga 模式是 Seata 提供的长事务解决方案。也分为两个阶段:

  • 一阶段: 直接提交本地事务
  • 二阶段: 成功则什么都不做;失败则通过编写补偿业务来回滚

image.png

优点:

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

缺点:

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

三、代码实现

具体代码使用,可参考 Seata 官方文档

这里需要注意每个模式需要的准备工作不同,如AT模式下就需要准备如下几点:

  1. lock_table 导入 Seata 数据库,就是 TC 服务关联的数据库;
  2. undo_log 导入业务相关的数据库;
  3. 修改事务模式。

四、对比总结

对比维度 XA AT TCC Saga
数据一致性 强一致性 弱一致性 最终一致性 最终一致性
隔离性 完全隔离 基于全局锁 基于资源预留 无隔离
代码入侵
性能 较低
依赖本地事务 依赖 依赖 不依赖 不依赖
场景 一致性,隔离性要求高的业务场景。 继续关系型数据库的大多分布式事务的场景均适合。 对性能要求高,且有非关系型数据库参与的事务。 业务流程较长,数据时效性要求较低的场景。

参考:

[1] B站黑马. Seata从入门到进阶.

与Seata原理浅析相似的内容:

Seata原理浅析

前言 Seata是阿里开源的分布式事务解决方案,本文将详细介绍 Seata 的事务模式、原理以及使用。了解之前需清楚什么是分布式事务。 一、什么是 Seata Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了XA、AT、TCC 和 S

聊聊Seata分布式解决方案AT模式的实现原理

### 什么是Seata分布式事务解决方案 Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式的分布式解决方案。 ### AT模式 AT模式目前来看是Seata框架独有的一种模式,其它的分布式框架上

分布式事务 —— SpringCloud Alibaba Seata

Seata 简介 传统的单体应用中,业务操作使用同一条连接操作不同的数据表,一旦出现异常就可以整体回滚。随着公司的快速发展、业务需求的变化,单体应用被拆分成微服务应用,原来的单体应用被拆分成多个独立的微服务,分别使用独立的数据源,业务操作需要调用三个服务来完成。此时每个服务内部的数据一致性由本地事务

基于Seata探寻分布式事务的实现方案

随着业务的快速发展、业务复杂度越来越高,几乎每个公司的系统都会从单体走向分布式,特别是转向微服务架构。随之而来就必然遇到分布式事务这个难题,这篇文章通过seata框架总结了分布式事务的几种解决方案。

分布式事务:XA和Seata的XA模式

上一篇内容《从2PC和容错共识算法讨论zookeeper中的Create请求》介绍了保证分布式事务提交的两阶段提交协议,而XA是针对两阶段提交提出的接口实现标准,本文则对XA进行介绍

[转帖]工信部电子标准院授予阿里巴巴9个开源项目“优秀”评级

http://blog.itpub.net/31545803/viewspace-2932061/ 1月13日消息,工信部电子标准院近日公布第二批通过开源项目成熟度评估的开源项目名单,阿里巴巴主导的Flink、Dubbo、龙蜥操作系统、Seata、Nacos等多个开源项目获得“优秀”评级。 电子标准

Springcloud2021+Nacos2.2+Dubbo3+Seata1.6实现分布式事务

> 示例代码地址:https://gitee.com/gtnotgod/Springcloud-alibaba.git 更详细参考Gitee完整的项目:https://gitee.com/gtnotgod/Springcloud-alibaba.git # 官网下载Nacos > https://n

[转帖]RAID 5写带宽11.7GB/s:当SAS 24G阵列卡嵌入PCIe Switch

https://zhuanlan.zhihu.com/p/576562821 引言:在SAS/SATA RAID卡开始转向Tri-Mode即支持NVMe之后,关于软硬RAID哪个更好的讨论还在继续。而Broadcom和Microchip这两家大厂的手里,正好都掌握着PCIe Switch芯片技术。不

[转帖]焱融全闪系列科普| 为什么 SSD 需要 NVMe?

https://xie.infoq.cn/article/7026237b455c7d62f33afc4a9 NVMe 的由来 目前机械硬盘大多数使用 SATA (Serial ATA Advanced Host Controller Interface) 接口,接口协议为 AHCI,是 Intel

[转帖](三)固态硬盘的接口与协议

https://zhuanlan.zhihu.com/p/415817808 目前市场上的固态硬盘简单来说共有SATA、PCIE、M.2和U.2四种接口类型。 早期,为了更适应于超极本这类超薄设备的使用环境,针对便携设备开发的mSATA(mini SATA)接口应运而生。你可以把它看作标准SATA接