说说分布式事务(三)

4

最终一致性(一)

TCC

简介

TCC是由支付宝架构师提供的一种柔性解决分布式事务解决方案,主要包括三个步骤:
图片描述

TCC流程

TCC的关键流程如下图(以下单和扣减库存为例子)
图片描述
Q: 预生成订单失败了,为什么要通过TCC执行预处理数据回滚?

A: 可能预生成订单成功,但是接口返回失败(超时失败),所以预处理在某些情况下是有预处理数据,需要清

TCC异常场景

在整个流程,我们主要需要关注的是cancel失败和confirm失败引起的数据不一致现象

图片描述

注意事项

  1. TCC服务支持接口失败重试,所以对TCC暴露的接口都需要满足幂等性(根据事务Id很好满足)

  2. 基于TCC的中心化事务一致性解决方法,各个应用服务器如果需要感知某次事务是否成功的成本很高,所以对于自身而言进行事务补偿成本就会很高.举个例子:
    图片描述

1⃣️每次成功的执行本应用服务器的事务以后,都需要把成功执行的事务Id记录
2⃣️继续confirm或者将confirm完的数据回滚,对用户都很不友好,特别是需要confirm订单或者回滚订单数据
3⃣️可以根据事务开始的时间,并且设计一个事务超时时间,如果在这个时间范围以外事务还没有处理完成,就可以当做这个事务已经失败,将预处理数据删除
总体来说,事务补偿机制,心智负担过于沉重.所以只能依赖TCC服务器的失败重试机制,如果失败重试机制不能处理,只能人肉去处理(建议全程人肉,因为同时进行失败重试和人肉的话,因为如果失败重试和人肉都在操作同一条数据,还需要考虑这种竞争的场景,对重试次数需要限定)

后记

  1. 是否一定需要TCC服务器?
    不一定,可以让交易链路来充当TCC服务器的角色,但是长期来看,TCC相当于是一个公用的组件,所以其它地方也需要TCC分布式事务,可以公用这一个组件(交易链路可以完成TCC所能完成的一切操作,把TCC单独部署一个服务,仅仅是考虑整个系统的抽象结构和功能复用)

  2. 这里说的预处理,指的是什么?
    在整个分布式事务中预处理的含义其实很广泛,比如订单,所谓的预处理就是生成订单,但是用户真实是看不到这些订单的,至于具体实现是在一张新表中记录还是在原有的订单表是加上标记位,具体实现方式由自己统筹考虑(当然还需要考虑记录事务Id);像减库存这种预处理,可以直接减少原始库存,再通过另外一张表来记录这次事务Id操作了哪个Sku的库存数量,当然也可以不减少库存只记录操作,但是这种方式在计算实际库存的时候复杂度会提高(需要减掉预处理的那部分)


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

沈子平 · 2018年01月04日

请教下,如果try的时候预留资源成功,但是调用方服务宕机了,TCC会怎么来释放预留资源?

回复

0

可以看下「注意事项」这一节,可以通过定时任务去扫预处理的表,或者其它方式也是可以的

iMouseWu 作者 · 2018年02月24日
YukiYukiKun · 2018年12月20日

TCC和2PC有什么本质性的区别吗?这看起来是一个稍作拆分的2PC流程。
2PC原有的阻塞问题和主从同时宕机状态丢失的问题,TCC是如何解决的呢?
阿里有发表相关论文供参考吗?

回复

YukiYukiKun · 2018年12月20日

好吧,这种做法看似有很多问题,但是通过重试幂等操作,预留一定的节点资源,加上适当的人为干预,实践效果应该不错。
这也是理论和工程的不同吧。

回复

0

是的,可以理解为TCC是2PC的一个最佳的实践
还有一个需要注意的是,2PC其实在操作过程中是锁资源保证一致性,但是TCC其实主要保障的是最终一致性

iMouseWu 作者 · 1月1日
载入中...