深度剖析分布式事务之 AT 与 XA 对比
来源:SegmentFault
时间:2023-02-23 12:47:16 310浏览 收藏
知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个数据库开发实战,手把手教大家学习《深度剖析分布式事务之 AT 与 XA 对比》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!
AT 这种事务模式是阿里开源的seata主推的事务模式,本文会详解AT的原理,并将它与XA模式进行比较
原理
AT 从原理上面看,与 XA 的设计有很多相近之处。XA 是数据库层面实现的二阶段提交, AT 则是应用/驱动层实现的二阶段提交。建议您了解了XA相关的知识后,来阅读这篇文章,这样能够更快更好的掌握 AT 的原理与设计。
AT的角色和XA一样分为3个,但是起了不一样的名称,大家注意分辨:
- RM 资源管理器,是业务服务,负责本地数据库的管理,与XA中的RM一致
- TC 事务协调器,是Seata服务器,负责全局事务的状态管理,负责协调各个事务分支的执行,相当于XA中的TM
- TM 事务管理器,是业务服务,负责全局事务的发起,相当于XA中的APP
AT 的第一阶段为prepare,它在这一阶段会完成以下事情:
- RM 侧,用户开启本地事务
RM 侧,用户每进行一次业务数据修改,假设是一个update语句,那么 AT 会做以下内容:
- 根据update的条件,查询出修改前的数据,该数据称为BeforeImage
- 执行update语句,根据BeforeImage中的主键,查询出修改后的数据,该数据称为AfterImage
- 将BeforeImage和AfterImage保存到一张undolog表
- 将BeforeImage中的主键以及表名,该数据称为lockKey,记录下来,留待后续使用
RM 侧,用户提交本地事务时,AT 会做以下内容:
- 将2.4中记录的所有的lockKey,注册到 TC(即事务管理器seata)上
- 3.1中的注册处理会检查 TC 中,是否已存在冲突的主键+表名,如果有冲突,那么AT会睡眠等待后重试,没有冲突则保存
- 3.1成功完成后,提交本地事务
如果 AT 的第一阶段所有分支都没有错误,那么会进行第二阶段的commit,AT 会做以下内容:
- TC 会将当前这个全局事务所有相关的lockKey删除
- TC 通知与当前这个全局事务相关的所有业务服务,告知全局事务已成功,可以删除undolog中保存的数据
- RM 收到通知后,删除undolog中的数据
如果 AT 的第一阶段有分支出错,那么会进行第二阶段的rollback,AT 会做以下内容:
- TC 通知与当前这个全局事务相关的所有业务服务,告知全局事务失败,执行回滚
RM 收到通知后,对本地数据的修改进行回滚,回滚原理如下:
- 从undolog中取出修改前后的BeforeImage和AfterImage
- 如果AfterImage与数据库中的当前记录校验一致,那么使用BeforeImage中的数据覆盖当前记录
- 如果AfterImage与数据库中的当前记录不一致,那么这个时候发生了脏回滚,此时需要人工介入解决
- TC 待全局事务所有的分支,都完成了回滚,TC 将此全局事务所有的lockKey删除
问题分析
AT 模式的一个突出问题是rollback中2.3的脏回滚难以避免。以下步骤能够触发该脏回滚:
- 全局事务g1对数据行A1进行修改 v1 -> v2
- 另一个服务将对数据行A1进行修改 v2 -> v3
- 全局事务g1回滚,发现数据行A1的当前数据为v3,不等于AfterImage中的v2,回滚失败
这个脏回滚一旦发生,那么分布式事务框架没有办法保证数据的一致性了,必须要人工介入处理。想要避免脏回滚,需要把所有对这个表的写访问,都加上特殊处理(在Seata的Java客户端中,需要加上GlobalLock注解)。这种约束对于一个上了一定规模的复杂系统,是非常难以保证的。
AT vs XA
上述脏回滚问题,在 XA 事务中不会出现,因为 XA 事务是在数据库层面实现的,当另一个服务对为数据行A1进行修改时,会因为行锁被阻塞,与普通事务的表现完全一样,不会产生问题。
另外 XA 不会发生脏读,而 AT 会发生脏读,考虑AT下的如下执行步骤:
- 全局事务g1对数据行A1进行修改 v1 -> v2
- 另一个服务将读取数据行A1,获得数据 v2
- 全局事务g1回滚,将数据行A1改回 v2 -> v1
这里面步骤2读取的数据是v2,是一个中间态数据。在Seata的手册中,虽然也有一些方法能够避免AT模式下,但是涉及到注解和sql改写,并不优雅。而在XA模式下,由于还没有进行xa commit,那么步骤2根据
MVCC读取到的数据依然是v1,没有AT模式中的脏读的困扰。
性能分析
从原理的详细步骤看,XA事务的性能高于AT,分析如下:
AT 模式下,RM侧,上述原理过程中,执行的SQL如下:
- 开启事务
- 查询BeforeImage数据
- 执行update
- 查询AfterImage数据
- 将BeforeImage,AfterImage插入到undolog中
- 提交事务
- 事务完成后,删除BeforeImage和AfterImage
而 XA 模式下,RM侧,执行的SQL如下:
- xa begin
- 执行update
- xa end
- xa prepare
- xa commit
两者对比,相关的开启/提交事务是两个模式都需要的,性能差异不大。但是从执行的DML操作来看,AT 下的 SQL 数量为:3 writes,2 read,比 XA 下仅一个update多出许多,因此在性能上会有较大的差距
从上述理论分析,XA 事务性能会大幅高于AT,应当可以在postgres数据库上验证出来;而mysql数据库,在当前的5.8版本上,由于xa prepare后,需要将当前连接断开才能够在其他连接上xa commit,所以会有一个重新创建连接的开销,最终性能对比参考下一节。
性能实测
上述进行了理论上的性能分析,我同时也做了性能实测,详细的测试过程和结果数据,参考 xa-at bench
dtm实现的XA事务,为了在极端情况下,也能保证XA事务能够正确的被清理,会在业务事务中对子事务屏障表进行插入,因此会比上述理论分析中,多一个sql写入。
我们可以看到,最终的结果XA性能优于AT。如果未来Mysql完善了XA的实现,可以不用关闭当前连接也能够允许其他连接提交xa事务,那么XA的性能还能够提升一大截。
AT的意义
mysql在版本5.6中,xa相关API存在bug。如果当前连接在xa prepare之后,连接断开,那么这个连接未完成的事务会被自动回滚。这样的bug导致mysql的XA模式是无法保证正确性的,在各种应用crash中,可能导致数据不一致。因此AT在mysql的5.6版本及更低版本使用中,是具有很高应用价值的。
另外部分大厂的数据库是禁止使用XA事务的,这种特定场景下,选型AT模式,也是合理的。
对于其他场景,建议优先考虑 XA 事务。
小结
欢迎访问 https://github.com/dtm-labs/dtm 并star支持我们
到这里,我们也就讲完了《深度剖析分布式事务之 AT 与 XA 对比》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于mysql的知识点!
-
499 收藏
-
244 收藏
-
235 收藏
-
194 收藏
-
157 收藏
-
418 收藏
-
339 收藏
-
279 收藏
-
189 收藏
-
208 收藏
-
174 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习
-
- 单纯的故事
- 这篇文章内容真是及时雨啊,好细啊,受益颇多,mark,关注作者大大了!希望作者大大能多写数据库相关的文章。
- 2023-05-16 09:38:25
-
- 风中的夕阳
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢大佬分享博文!
- 2023-04-14 10:47:13
-
- 大气的纸鹤
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者大大分享文章!
- 2023-04-06 03:42:17
-
- 开朗的咖啡豆
- 这篇文章真及时,好细啊,写的不错,已加入收藏夹了,关注作者了!希望作者能多写数据库相关的文章。
- 2023-02-24 04:24:57