首页 > 其他资讯 > Seata 的 TCC 模式才是强一致性的最优解!!架构师必知

Seata 的 TCC 模式才是强一致性的最优解!!架构师必知

时间:26-04-24

最终一致性vs强一致性

为分布式事务选择一致性模型,首要任务是审视业务场景:你的业务逻辑,是否必须强一致,还是能够容忍最终一致?

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

要做出准确判断,必须清晰理解两者的本质区别。

核心的判别标准非常聚焦:在整个事务的生命周期内,是否存在任何不符合业务语义的“中间态”数据被暴露。

这个概念听起来抽象,我们用一个典型场景来剖析。以电商领域的“扣减库存-创建订单”流程为例。

业务逻辑是线性的:库存服务完成扣减后,再调用订单服务生成订单。那么,如何界定其一致性?

业务期望的最终状态只有两种:库存成功扣减且订单创建完成;或者库存未动且订单也未生成。问题的关键在于,是否会出现第三种“矛盾”状态:库存已扣但订单缺失;或库存未扣但订单已生成。这两种,就是典型的非预期中间状态。

接下来,我们将依据这一标准,深入对比Seata的AT模式与TCC模式,分析它们各自产生的数据状态。

Seata的AT模式

通过下面的时序图,我们可以清晰地梳理其执行脉络:

在步骤8,库存服务的本地数据库事务就已提交。请注意,此时全局事务尚未提交,订单服务甚至还未被调用。这就引入了一个潜在问题:若此时有其他并发查询请求读取该商品库存,它将读到什么?答案是已被扣减后的数量。然而,与之对应的订单数据却根本不存在。这读取到的,正是非业务预期的中间状态数据。

当然,如果后续订单服务调用成功,订单顺利生成,这个问题就被掩盖了,数据最终达成一致。但若订单服务失败,全局事务将回滚,库存数量会被恢复。然而,之前那个读到“已扣减库存”的查询,获取的已然是一份“脏数据”。在此场景下,AT模式提供的是“最终一致性”保障。

本质上,Seata AT模式是对传统两阶段提交(2PC)协议的一种优化。优化的核心在于分支事务的提交时机。经典2PC要求所有分支事务在准备阶段完成后均等待,直到协调者发出提交指令才一并提交本地事务,这导致数据库锁持有时间过长,影响性能。AT模式的改进在于:分支事务在完成本地操作后立即提交,释放数据库锁,从而换取更高的并发吞吐量。

一个关键细节在于:库存服务与订单服务持有的全局锁,在正常提交与异常回滚两种路径下的释放时机不同,且释放速度存在本质差异。这正是AT模式在高成功率业务场景下性能表现优异的核心机制。

这也解释了为何在业务成功率极高(例如超过99%)的场景中,Seata AT模式能够展现出卓越的性能。

此外,需要考虑一个极端场景。在AT模式中,若第一阶段所有分支均报告成功,事务管理器发起全局提交,但进入第二阶段后,订单服务在提交时失败(可能由于网络闪断、服务宕机或数据库异常)。这属于“提交阶段异常”。

根据2PC及Seata的设计原则,一旦事务管理器决定提交(进入第二阶段),所有分支事务必须最终提交,不可再回滚。那么,第二阶段某个分支提交失败如何处理?事务协调器会负责持续重试,直至成功。这通常依赖于协调器内部的重试队列或定时任务来保证。由于第一阶段已通过业务校验并锁定资源,理论上第二阶段的提交操作(主要是释放锁、清理日志)最终必然成功。

Seata的TCC模式

TCC模式与Seata AT最根本的区别在于:它不依赖于数据库原生的ACID事务与锁机制,而是要求开发者通过业务代码,显式地实现资源的预留、确认与取消。

首先分析Try阶段(这是整个模式的核心):

对于库存服务,并非直接扣减,而是执行“冻结”操作。例如商品总库存100件,Try阶段冻结1件,可用库存显示为99件。注意,这1件并未被实际消耗,若后续流程失败,它可以被“解冻”归还。对于订单服务,也并非直接生成有效订单,而是创建一个处于“中间态”(如“待确认”)的订单记录,或仅预占一个订单号。此阶段的“锁”,是业务逻辑层面的锁(例如通过一个`frozen`字段标记),而非数据库的排他锁。这意味着其他事务仍可操作这行数据(只要不触及已冻结部分),从而实现了更高的并发度。

再看Confirm阶段:

此阶段仅执行确认操作。由于资源已在Try阶段预留妥当,Confirm阶段理论上只应成功,不应失败(除非遭遇数据库宕机等极端故障)。同时,Confirm操作的代码必须具备幂等性,以应对网络抖动导致的重复调用。

最后是Cancel阶段(图中未展示,但其逻辑与Confirm相反):

如果Try阶段任一环节失败,事务协调器将调用各服务的Cancel方法。库存服务会将冻结库存加回可用库存(解冻);订单服务则会将“待确认”订单删除或标记为“已取消”。

那么,为何说TCC模式能提供强一致性?关键在于其对“中间状态”的业务定义。

以Try阶段为例,参照上图。在库存服务执行完`tryDeductStock`(步骤6)并提交本地事务后,若有其他线程查询商品库存,它将看到的状态是:【总库存不变,但可用库存-1,冻结库存+1】。

请注意,这虽然是业务流程中的一个中间状态,但它完全符合业务预期,不存在任何歧义。无论后续流程走向如何——是订单创建失败导致库存解冻,还是订单创建成功导致冻结库存被正式消耗——这些状态变迁都严格遵循预先定义的业务语义。因此,TCC模式实现了数据的强一致性。

必须强调:TCC所能提供的强一致性,高度依赖于业务状态定义的准确性与无二义性。如果在Try阶段完成后,数据状态本身就存在逻辑矛盾,那么这已非TCC模式能够解决的问题,而需要在业务架构设计层面进行修正。


这就是Seata 的 TCC 模式才是强一致性的最优解!!架构师必知的全部内容了,希望以上内容对小伙伴们有所帮助,更多详情可以关注我们的菜鸟游戏和软件相关专区,更多攻略和教程等你发现!

热搜     |     排行     |     热点     |     话题     |     标签

手机版 | 电脑版 | 客户端

湘ICP备2022003375号-1

本站所有软件,来自于互联网或网友上传,版权属原著所有,如有需要请购买正版。如有侵权,敬请来信联系我们,cn486com@outlook.com 我们立刻删除。