出处:https://segmentfault.com/a/1190000005969526
简介
TCC
是由支付宝架构师提供的一种柔性解决分布式事务解决方案,主要包括三个步骤:
TCC流程
TCC
的关键流程如下图(以下单和扣减库存为例子)
Q: 预生成订单失败了,为什么要通过TCC
执行预处理数据回滚?
A: 可能预生成订单成功,但是接口返回失败(超时失败),所以预处理在某些情况下是有预处理数据,需要清理
TCC异常场景
在整个流程,我们主要需要关注的是cancel
失败和confirm
失败引起的数据不一致现象
注意事项
-
TCC
服务支持接口失败重试,所以对TCC
暴露的接口都需要满足幂等性(根据事务Id很好满足) -
基于
TCC
的中心化事务一致性解决方法,各个应用服务器如果需要感知某次事务是否成功的成本很高,所以对于自身而言进行事务补偿成本就会很高.举个例子:
1⃣️每次成功的执行本应用服务器的事务以后,都需要把成功执行的事务Id记录
2⃣️继续confirm
或者将confirm
完的数据回滚,对用户都很不友好,特别是需要confirm
订单或者回滚订单数据
3⃣️可以根据事务开始的时间,并且设计一个事务超时时间,如果在这个时间范围以外事务还没有处理完成,就可以当做这个事务已经失败,将预处理数据删除
总体来说,事务补偿机制,心智负担过于沉重.所以只能依赖TCC
服务器的失败重试机制,如果失败重试机制不能处理,只能人肉去处理(建议全程人肉,因为同时进行失败重试和人肉的话,因为如果失败重试和人肉都在操作同一条数据,还需要考虑这种竞争的场景,对重试次数需要限定)
后记
-
是否一定需要TCC服务器?
不一定,可以让交易链路来充当TCC
服务器的角色,但是长期来看,TCC
相当于是一个公用的组件,所以其它地方也需要TCC
分布式事务,可以公用这一个组件(交易链路可以完成TCC
所能完成的一切操作,把TCC
单独部署一个服务,仅仅是考虑整个系统的抽象结构和功能复用) -
这里说的预处理,指的是什么? 在整个分布式事务中预处理的含义其实很广泛,比如订单,所谓的预处理就是生成订单,但是用户真实是看不到这些订单的,至于具体实现是在一张新表中记录还是在原有的订单表是加上标记位,具体实现方式由自己统筹考虑(当然还需要考虑记录事务Id);像减库存这种预处理,可以直接减少原始库存,再通过另外一张表来记录这次事务Id操作了哪个Sku的库存数量,当然也可以不减少库存只记录操作,但是这种方式在计算实际库存的时候复杂度会提高(需要减掉预处理的那部分)