Seata-AT如何保证分布式事务一致性

Seata 是一款开源的分布式事务解决方案,star高达18100+,社区活跃度极高,致力于在微服务架构下提供高性能和简单易用的分布式事务服务,本文将剖析Seata-AT的实现原理,让用户对AT模式有更深入的认识.
作者:陈健斌(funkye) github id: a364176773

目录

  1. Seata 事务模式是什么?
  2. AT模式是什么?
  3. AT如何保证分布式事务一致性?
  4. Seata近期规划;
  5. 总结;

Seata事务模式是什么?

1.1Seata对事务的定义

Seata 定义了全局事务的框架。
全局事务 定义为若干 分支事务 的整体协调:
1.TM 向 TC 请求发起(Begin)、提交(Commit)、回滚(Rollback)全局事务。
2.TM 把代表全局事务的 XID 绑定到分支事务上。
3.RM 向 TC 注册,把分支事务关联到 XID 代表的全局事务中。
4.RM 把分支事务的执行结果上报给 TC。(可选)
5.TC 发送分支提交(Branch Commit)或分支回滚(Branch Rollback)命令给 RM。

Seata 的 全局事务 处理过程,分为两个阶段:
执行阶段 :执行 分支事务,并 保证 执行结果满足是 可回滚的(Rollbackable) 和 持久化的(Durable)。
完成阶段: 根据 执行阶段 结果形成的决议,应用通过 TM 发出的全局提交或回滚的请求给 TC,
TC 命令 RM 驱动 分支事务 进行 Commit 或 Rollback。
Seata 的所谓 事务模式 是指:运行在 Seata 全局事务框架下的 分支事务 的行为模式。
准确地讲,应该叫作 分支事务模式。
不同的 事务模式 区别在于 分支事务 使用不同的方式达到全局事务两个阶段的目标。
即,回答以下两个问题:
执行阶段 :如何执行并 保证 执行结果满足是 可回滚的(Rollbackable) 和 持久化的(Durable)。
完成阶段: 收到 TC 的命令后,做到事务的回滚/提交

1.2 其它二阶段事务如何在Seata事务框架下运转

1.2.1 TCC事务模式

首先,我们先来看下TCC事务是如何融合在Seata事务框架中:

可以发现,其实跟Seata的事务框架图长得非常的像,而区别呢就是我们的RM负责管理的就是我们的一阶段的try执行和二阶段的confirm/cancel,一样是由TM进行事务的Begin(发起),RM被TM调用后执行一阶段的Try方法,等待调用链路走完的时候,TM向TC告知二阶段决议,此时TC对RM驱动二阶段执行(下发通知,RM执行confirm/cancel).

1.2.1 XA事务模式

如图所示,XA模式其实就是Seata底层利用了XA接口,在一阶段二阶段时自动处理.如一阶段时,XA的RM通过代理用户数据源,创建XAConnection,进行开启XA事务和XAprepare(此时XA的任何操作都会被持久化,即便宕机也能恢复),在二阶段时,TC通知RM进行XA分支的Commit/Rollback操作.

AT模式是什么?

首先我们来看一个例子:

一阶段: 业务sql:update product set name = ‘GTS’ where name = ‘TXC’;

可以看到一阶段的时候对用户是无感知的,业务sql是什么,还是什么.此时我们来简单说下AT这个时候会做那些事?

解析sql并查询得到前镜像: select id, name, since from product where name = ‘TXC’;

执行业务sql后,再查询执行后的数据作为后镜像: select id, name, since from product where id = 1;

二阶段:

提交: 仅需把事务相关信息删除即可.(理论上不删除也没问题)

回滚: 取出前镜像进行回滚

通过上述简单的例子,其实可以发现,AT模式就是自动补偿式事务,那AT具体都做了哪些呢?我们接下来看.

AT如何保证分布式事务一致性?

我们来看这个图:

可能刚看到会有疑问对吧?其实这个就是无侵入式,AT模式的做法示意图,首先用户还是从接口进入,到达了事务发起方,此时对业务开发者来说,这个发起方入口其实就是一个业务接口罢了,一样的执行业务sql,一样的return响应信息给客户端并没有什么改变.而背后就是用户的sql被Seata代理所托管,Seata-AT模式能感知到用户的所有sql,并对之进行操作,来保证一致性.

但是Seata-AT是怎么做到无侵入的呢?我们接着看

首先我们可以看到如图所示,应用启动时,Seata会自动把用户的DataSource代理,还对JDBC操作熟悉的用户其实对DataSource还是比较熟悉的,拿到了DataSource,就等于掌握了数据源连接,也就能在背后做些"小动作",此时该对用户也是无感知无入侵.

之后业务有请求进来,执行业务sql时,Seata会解析用户的sql,提取出表元数据,生成前镜像,再通过执行业务sql,保存执行sql后的后镜像(至于后镜像的用户之后会说到),再生成行锁,再注册分支是携带到Seata-Server 也就是TC端.

此时在Client端的一阶段操作就已经完成了,无感知,无入侵.此时如果我们思考下,会发现这里其实有一个行锁,那么这个行锁是干嘛的呢?这就是要接着讲到Seata-AT是如何保证分布式下的事务隔离性,这里我们直接拿官网的示例来说.

2.1写隔离

  • 一阶段本地事务提交前,需要确保先拿到 全局锁
  • 拿不到 全局锁 ,不能提交本地事务。
  • 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

以一个示例来说明:

两个全局事务 tx1 和 tx2,分别对 a 表的 m 字段进行更新操作,m 的初始值 1000。

tx1 先开始,开启本地事务,拿到本地锁,更新操作 m = 1000 - 100 = 900。本地事务提交前,先拿到该记录的 全局锁 ,本地提交释放本地锁。 tx2 后开始,开启本地事务,拿到本地锁,更新操作 m = 900 - 100 = 800。本地事务提交前,尝试拿该记录的 全局锁 ,tx1 全局提交前,该记录的全局锁被 tx1 持有,tx2 需要重试等待 全局锁

tx1 二阶段全局提交,释放 全局锁 。tx2 拿到 全局锁 提交本地事务。

如果 tx1 的二阶段全局回滚,则 tx1 需要重新获取该数据的本地锁,进行反向补偿的更新操作,实现分支的回滚。

此时,如果 tx2 仍在等待该数据的 全局锁,同时持有本地锁,则 tx1 的分支回滚会失败。分支的回滚会一直重试,直到 tx2 的 全局锁 等锁超时,放弃 全局锁 并回滚本地事务释放本地锁,tx1 的分支回滚最终成功。

因为整个过程 全局锁 在 tx1 结束前一直是被 tx1 持有的,所以不会发生 脏写 的问题。

这个时候隔离性相比大家已经比较明白了,此时一阶段的大部分操作相信大家也比较明白了,此时我们应该继续往下一阶段继续解析.

2.2 AT 模式二阶段处理

我们由上图可见在二阶段提交时,其实TC仅是下发一个把之前一阶段做记录的undoLog删除,并把相关事务信息,如行锁删除,让之后因为在竞争锁被阻塞的事务顺利进行.

而二阶段是回滚时,则要多做一些处理.

首先在Client端收到TC告知的二阶段是回滚时,会去查到对应的事务的undolog,取出后镜像,对比当前数据的数据(因为SeataAT是从业务应用层面进行保护分布式事务,如果此时在数据库层面直接修改了库内信息,这个时候SeataAT的行锁是不起到隔离性),如果出现了在全局事务以外的数据修改,此时判定为脏写,而Seata因为无法感知这个脏写如何发生,此时只能打印日志和触发异常通知,告知用户需要人工介入(规范修改数据入口可避免脏写).

而如果没有发生脏写就比较简单了,拿出前镜像,因为我们都知道事务是需要有原子性了,要么一起发生,要么都不发生,此时前镜像记录了发生之前的数据,进行回滚后,就达到了类似本地事务那样的原子性效果.回滚后,再把事务相关信息,如undolog,行锁进行删除.二阶段回滚算是告一段落了.

既然介绍完了AT模式的一阶段及二阶段的原理思想方式,那么AT在Seata的分布式事务框架下是怎么样的呢?

我们可以看到,AT与其它事务模式在Seata事务框架中,会多出一个undolog的依赖(相对其它模式的入侵点),但是除此之外,对业务来说,几乎是零入侵性,这也就是为什么AT模式在Seata中受众广泛.

2.3 AT 模式与Seata支持的其它二阶段模式区别

首先我们应该明白,目前为止,不存在有任何一种分布式事务的可以满足所有场景.

无论 AT 模式、TCC 模式还是 Saga 模式,这些模式的提出,本质上都源自 XA 规范对某些场景需求的无法满足.

我们分为3点来做出对比:

  • 数据锁定

AT 模式使用 全局锁 保障基本的 写隔离,实际上也是锁定数据的,只不过锁在 TC 侧集中管理,解锁效率高且没有阻塞的问题.

TCC模式 无锁,利用本地事务排他锁特性,可预留资源,在全局事务决议后执行相应操作.

XA 模式 在整个事务处理过程结束前,涉及数据都被锁定,读写都按隔离级别的定义约束起来.

  • 死锁(协议阻塞)

XA 模式 prepare 后(老版本的数据库中,需要XA END后,再下发prepare(三阶段由来)),分支事务进入阻塞阶段,收到 XA commit 或 XA rollback 前必须阻塞等待。

AT 可支持降级,因为锁存储再TC侧,如果Seata 出现bug或者其它问题,可直接降级,对后续业务调用链无任何影响.

TCC 无此问题.

  • 性能

性能的损耗主要来自两个方面: 一方面,事务相关处理和协调过程,增加单个事务的 RT;另一方面,并发事务数据的锁冲突,降低吞吐.其实主要原因就是上面的协议阻塞跟数据锁定造成.

XA 模式它的一阶段不提交,在大并发场景由于锁存储再多个资源方(数据库等),加剧了性能耗损

AT 模式 锁粒度细至行级(需要主键),且所有事务锁存储再TC侧,解锁高效迅速.

TCC 模式 性能最优,仅需些许RPC开销,及2次本地事务的性能开销,但是需要符合资源预留场景,且是对业务侵入性较大(需要业务开发者每个接口分为3个,一个try,2个二阶段使用的confirm和cancel).

可能很多同学对XA和AT的锁&协议阻塞不是特别理解,那么我们直接来看下图

可以试着猜一下是哪个是XA?其实下图的是XA,因为它带来的锁粒度更大,且锁定时间更久,导致了并发性能相对AT事务模型来说,差的比较多,所以至今,XA模式的普及度都不很太高.

Seata近期规划

  • 控制台

首先控制台是我们Seata用户暴露已久的一个问题,没有一个可视化界面,使得用户对Seata的可靠性出现了怀疑,更由于没有控制台也局限了很多在Seata上可人工介入分布式事务的可能性等问题,所以未来在1.5.0的版本我们会带来控制台的加入,也欢迎更多的同学加入进来一起共建!

  • Raft集成

Raft集成的原因,可能大部分用户不是特别知晓,首先我们要知道目前TC端的事务信息都是存储再外部存储器,比如数据库,redis,mongodb(PR阶段),这就造成了如果外部存储宕机,会造成Seata-Server集群的完全不可用,即便Server是集群部署,有10个甚至更多节点,都会因此而不可用.这是不可接受的.

所以引入Raft来让每个Seata-Server的事务信息达到一致,即便某个节点宕机,也不会破坏事务信息准确性,从而也让分布式事务的一致性得到了更好的保证.(关于Seata-Server raft的实现之后会以新篇章来分享)

  • undoLog压缩

这个是我们1.5.0 AT模式比较大的性能优化,由于一阶段操作的数据多且大,因为Seata在背后为用户插入了undolog信息,由此可能也会变得大,有造成了入库缓慢的可能,所以我们要把undolog进行压缩,使undolog的插入不再成为AT事务在分支数据量大的时候成为一个大的心梗开销.

以下是我们Seata的交流群欢迎大家加入

钉钉: 32033786

QQ: 216012363

总结

AT 说到底就是实现对资源操作的代理,并记录原先&变更后的状态,并用锁保证该数据的隔离性.在调用链中出现异常时,还原所有分支数据,达到分布式事务下的’原子性’

未来呢? redis,mongodb,mq? 尽情期待.

Seata项目的最核心的价值在于:

构建一个全面解决分布式事务问题的 标准化 平台。

基于 Seata,上层应用架构可以根据实际场景的需求,灵活选择合适的分布式事务解决方案,非常欢迎大家参与到项目的建设中,共同打造一个标准化的分布式事务平台。

Seata-AT如何保证分布式事务一致性相关推荐

  1. Seata-AT 如何保证分布式事务一致性

    作者 | 陈健斌(funkye) github id: a364176773 来源|阿里巴巴云原生公众号 Seata 是一款开源的分布式事务解决方案,star 高达 18100+,社区活跃度极高,致力 ...

  2. 22、Camunda 补偿事件、事务子流程、分布式事务一致性

    Camunda 补偿事件.事务子流程.分布式事务一致性 总结 补偿事件 Compensation Event 事务子流程 事务子流程中如果有取消事件,必须要有边界取消中断事件 事务子流程外部可获取取消 ...

  3. seata分布式事务一致性锁机制如何实现的

    本文来说下seata分布式事务一致性锁机制是如何实现的 文章目录 概述 概述

  4. 使用MQ来保证分布式事务的最终一致性

    使用MQ来保证分布式事务的最终一致性 使用MQ来保证分布式事务的最终一致性 参考URL:https://www.bbsmax.com/A/obzbM9QVdE/ 生产者的逻辑 1.订单入库 2.消息记 ...

  5. 分布式事务一致性解决方案

    一.从数据一致性谈起↑ 一致性问题,"万恶之源"是数据冗余和分布并通过网络交互+网络异常是常态. 1.数据一致性的情形 主库.从库和缓存数据一致性,相同数据冗余,关系数据库,为保证 ...

  6. 分布式系统漫谈【拾】_分布式事务一致性:阿里方案

    上篇文章:分布式系统漫谈[玖]_分布式事务一致性:协议支持 其实对于生产环境的分布式事务一致,各大互联网公司都是自己实现的解决方案,总结起来无非是异步.补偿.实时查询.定期校对几种模式,大部分场景都是 ...

  7. 微服务seata 1.4.2 分布式事务TCC模式示例

    seata TCC模式和AT模式的基础环境是一样的,只是在实现方式上有所区别,而且TCC模式还可以和AT模式混合使用. 关于AT模式示例,可以参考seata 1.4.2 分布式事务AT模式示例. TC ...

  8. 分布式数据库理论知识之CAP理论、ACID原则及分布式事务一致性算法

    1 CAP理论 分布式数据库的设计遵循CAP理论,即一个分布式系统不能同时满足Consistency(一致性).Availability(可用性)和Partition Tolerance(分区容忍性) ...

  9. 谈分布式事务一致性(2PC、3PC、TCC)、强一致性算法Paxos等关系

    一致性这个词重载的很厉害,在不同的语境和上下文中,它其实代表着不同的东西: 在事务的上下文中,比如ACID里的C,指的就是通常的一致性(Consistency) 在集群环境中,主从复制,如ZK(Pax ...

最新文章

  1. UE4创建第一人称射击游戏学习教程 Unreal Engine 4: Create Your Own First-Person Shooter
  2. 中序非递归遍历二叉树
  3. opengl 贴图坐标控制_材质贴图正确打开方式
  4. default argument given of parameter 的问题
  5. mysql数据库断电_MySQL 数据库忽然断电会丢数据吗转载
  6. 企业实战_08_MyCat 搭建Mysql 一主二从复制环境
  7. java环境变量自动设置_自动设置Java环境变量
  8. 业务逻辑数据层SqlDataSourcesql的输入参数
  9. 论文推荐|【KSII TIIS 2021】DP-LinkNet:一种用于古籍文档图像二值化的卷积网络(有源码)...
  10. qt qtoolbutton 弹出菜单方向_QT使用教程(三)之安装篇
  11. jsoup对象的使用
  12. 开始学习redhat8,安装redhat8虚拟机
  13. 优化程序性能(CSAPP)
  14. 使用MNIST数据集训练出来的模型预测自己手写数据
  15. 你们制作微信表情包都用了哪些软件?当然必备这3款
  16. Meson构建系统(二)
  17. Cocoa-专业术语
  18. 运营商,我看未必成为夕阳行业
  19. 关于如何将java桌面程序打包成exe可执行文件
  20. aix查看oracle客户端位数,查看系统硬件/软件配置/系统位数

热门文章

  1. 【Java】强制类型转换
  2. mac 安装 minicube
  3. C#(四十八)之StreamWriter StreamWriter使用方法及与FileStream类的区别
  4. CF#247(Div. 2)部分题解
  5. unity 如何处理不是2的幂次方的图片
  6. 四级口语计算机对话,四级英语口语对话常用句子
  7. AttributeError: module transformers has no attribute LLaMATokenizer解决方案
  8. SPL比SQL更难了还是更容易了?
  9. Docker制作含字体库的OpenJdk镜像
  10. 训练yolov7报错AssertionError: train: No labels in XX\train.cache. Can not train without labels