知识卡片

TCC的Try-Confirm-Cancel如何在分布式事务中保留隔离性

结构图卡

内容

[[可靠事件队列靠最大努力交付实现无回滚的最终一致]]完全没有隔离性,会导致 超售——两笔并发交易各自看到的库存都够卖,加起来却超过总库存。TCC事务 (Try-Confirm-Cancel)通过引入”预留资源”这个中间状态来弥补隔离性:Try 阶段检查所有业务的可行性并预留资源(比如把货款设为”冻结”状态、把商品设为 “冻结”状态,商家账户因为不需要预留可以跳过),只有全部参与方都反馈可行, 才进入Confirm阶段——不再做任何检查,直接消费Try阶段预留好的资源完成业务 (扣冻结的款、标记冻结的书出库、商家收款);只要有一方反馈不可行或超时, 则进入Cancel阶段,释放所有已预留的资源。Confirm和Cancel阶段都可能因网络 或业务异常需要重复执行,因此都必须设计成幂等的(最大努力交付)。TCC的 “预留”机制天然避免了超售,性能上也比2PC更好(业务执行阶段只操作预留资源, 不涉及跨服务的锁争用),但代价是业务侵入性强——需要业务代码自己实现预留/ 确认/取消三段逻辑,开发成本高,通常要借助Seata这类分布式事务中间件才能 落地。

结构图

flowchart TD
    Try[Try阶段: 检查可行性+预留资源] -->|全部可行| Confirm[Confirm阶段: 消费预留资源完成业务]
    Try -->|任一不可行或超时| Cancel[Cancel阶段: 释放预留资源]
    Confirm -->|异常时重复执行, 需幂等| Confirm
    Cancel -->|异常时重复执行, 需幂等| Cancel

参考来源

- 位置:《凤凰架构:构建可靠的大型分布式系统》第3章"事务处理"3.4.3节 "TCC事务"(源文件:_epub-src对应OEBPS/Text/chapter33.xhtml) - 结论依据:原文详述Try/Confirm/Cancel三阶段各自的操作(预留/消费/释放 资源),说明该方案天生适用于需要强隔离性的场景以避免超售,并指出其 业务侵入性强、通常需借助Seata等中间件实现,直接支撑本卡片结论。 - 原始内容:Try:尝试执行阶段,完成所有业务可执行性的检查(保障一致性), 并且预留好全部需要用到的业务资源(保障隔离性)……该方案天生适用于需要 强隔离性的分布式事务中。