侧边栏壁纸
  • 累计撰写 793 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论
标签搜索

目 录CONTENT

文章目录

分布式事务

Dettan
2021-04-10 / 0 评论 / 0 点赞 / 141 阅读 / 2,059 字
温馨提示:
本文最后更新于 2022-07-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
与本地事务相对, 又叫全局事务

一共三种方式


最终一致性


支付这种场景涉及到金钱需要保证强一致性。订单这种对于一致性要求没那么高。 可以通过Redis保证不超卖,订单取消等场景可以通过MQ异步更新库存。

XA 协议是 X/Open 提出的分布式事务处理标准。文中提到的 2PC、3PC、TCC、本地事务表、Seata in AT mode,无论哪一种,本质都是事务协调者协调各个事务参与者的本地事务的进度,使使所有本地事务共同提交或回滚,最终达成一种全局的 ACID 特性。在协调的过程中,协调者需要收集各个本地事务的当前状态,并根据这些状态发出下一阶段的操作指令。这个思想就是 XA 协议的要义,我们可以说这些事务模型遵守或大致遵守了 XA 协议。
基于消息中间件的最终一致性事务方案是互联网公司在高并发场景中探索出的一种创新型应用模式,利用 MQ 实现微服务之间的异步调用、解耦合和流量削峰,保证分布式数据记录的最终一致性。它显然不遵守 XA 协议。
对于某项技术,可能存在业界标准或协议,但实践者针对具体应用场景的需求或者出于简便的考虑,给出与标准不完全相符的实现,甚至完全不相符的实现,这在工程领域是一种常见的现象。TCC 方案如此、基于消息中间件的最终一致性事务方案如此、Seata in AT mode 模式也如此。而新的标准往往就在这些创新中产生。
你难道真的没有发现 2.6 节(基于消息中间件的最终一致性事务方案)给出的正确方案中存在的业务漏洞吗?请各位重新看下这张图,仔细品一品两个微服务的调用方向,把你的想法留在评论区吧 :-)



框架
以上说的都是理论和自己实现的方式,那么分布式事务就没有框架来解决我们的问题吗?
有,其实还不少,但是没有能扛旗者出现,要说有,阿里的开源框架 Seata 还有阿里云的 GTS。
GTS(Global Transaction Service 全局事务服务)是阿里云的中间件产品,只要你用阿里云,付钱就可以用 GTS。
Seata(Simple Extensible Autonomous Transaction Architecture)则是开源的分布式事务框架,提供了对 TCC、XA、Saga 以及 AT 模式的支持。
那么,GTS 和 Seata 有什么关系呢?
实际上最开始的时候他们都是基于阿里内部的 TXC(Taobao Transaction Constructor)分布式中间件产品,然后 TXC 经过改造上了阿里云就叫做 GTS。
之后阿里的中间件团队基于 TXC 和GTS做出了开源的 Seata,其中 AT(Automatic Transaction)模式就是 GTS 原创的方案。
至于现在的版本,可以大致认为他们就是一样的就行了,到 2020 年,GTS 已经全面兼容了 Seata 的 GA 版本。
图片来自阿里云官网 GTS
整个 GTS 或者 Seata 包含以下几个核心组件:
Transaction Coordinator(TC):事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
Transaction Manager(TM):控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
Resource Manager(RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。
无论对于 TCC 还是原创的AT模式的支持,整个分布式事务的原理其实相对来说还是比较容易理解。
1.
事务开启时,TM 向 TC 注册全局事务,并且获得全局事务 XID。
2.
这时候多个微服务的接口发生调用,XID 就会传播到各个微服务中,每个微服务执行事务也会向 TC 注册分支事务。
3.
之后 TM 就可以管理针对每个 XID 的事务全局提交和回滚,RM 完成分支的提交或者回滚。
核心组件定义-图片来自阿里云官网
AT 模式
原创的 AT 模式相比起 TCC 的方案来说,无需自己实现多个接口,通过代理数据源的形式生成更新前后的 UNDO_LOG,依靠 UNDO_LOG 来实现回滚的操作。
执行的流程如下:
1.
TM 向 TC 注册全局事务,获得 XID。
2.
RM 则会去代理 JDBC 数据源,生成镜像的 SQL,形成 UNDO_LOG,然后向 TC 注册分支事务,把数据更新和 UNDO_LOG 在本地事务中一起提交。
3.
TC 如果收到 commit 请求,则会异步去删除对应分支的 UNDO_LOG,如果是 rollback,就去查询对应分支的 UNDO_LOG,通过 UNDO_LOG 来执行回滚。
事务模式-AT-图片来自阿里云官网
TCC 模式
相比 AT 模式代理 JDBC 数据源生成 UNDO_LOG 来生成逆向 SQL 回滚的方式,TCC 就更简单一点了。
1.
TM 向T C 注册全局事务,获得 XID。
2.
RM 向 TC 注册分支事务,然后执行 Try 方法,同时上报 Try 方法执行情况。
3.
然后如果收到 TC 的 commit 请求就执行 Confirm 方法,收到 rollback 则执行 Cancel。
事务模式-TCC-图片来自阿里云官网
XA 模式
1.
TM 向 TC 注册全局事务,获得 XID。
2.
RM 向 TC 注册分支事务,XA Start,执行 SQL,XA END,XA Prepare,然后上报分支执行情况。
3.
然后如果收到 TC 的 commit 请求就执行 Confirm 方法,收到 rollback 则执行 Cancel。
事务模式-XA-图片来自阿里云官网
SAGA 模式
1.
TM 向 TC 注册全局事务,获得 XID。
2.
RM 向 TC 注册分支事务,然后执行业务方法,并且上报分支执行情况。
3.
RM 收到分支回滚,执行对应的业务回滚方法。
事务模式-Saga-图片来自阿里云官网
总结
这里从事务的 ACID 开始,向大家先说了 XA 是分布式事务处理的规范,之后谈到 2PC 和 3PC,2PC 有同步阻塞、单点故障和数据不一致的问题,3PC 在一定程度上解决了同步阻塞和单点故障的问题,但是还是没有完全解决数据不一致的问题。
之后说到 TCC、SAGA、消息队列的最终一致性的方案,TCC 由于实现过于麻烦和复杂,业务很少应用,SAGA 了解即可,国内也很少有应用到的,消息队列提供了解耦的实现方式,对于中小公司来说可能是较为低成本的实现方式。
最后再说目前国内的实现框架,云端阿里云的 GTS 兼容 Seata,非云端使用 Seata,它提供了 XA、TCC、AT、SAGA 的解决方案,可以说是目前的主流选择。
0

评论区