【回顾】 在上篇博客中,我们了解了处理分布式事务的柔性事务方案之一:可靠消息最终一致性方案。 本篇博客,继续了解又一柔性事务方案:TCC补偿性方案。 【TCC】 1. 什么是TCC? TCC分别对应Try、Confirm和Cancel三种操作,含义如下: - Try:预留业务资源 - Confirm:确认执行业务操作 - Cancel:取消执行业务操作 2. TCC与事务操作? 将TCC三个操作与关系型数据库的事务操作相比,可以发现有异曲同工之妙。 - Try操作是先把多个应用中的业务资源预留和锁定住,为后续的确认打下基础,类似的,DML操作要锁定数据库记录行,持有数据库资源。 - Confirm操作是在Try操作中涉及的所有应用均成功之后进行确认,使用预留的业务资源,和Commit类似。 - Cancel则是当Try操作中涉及的所有应用没有全部成功,需要将已成功的应用进行取消(即Rollback回滚)。其中Confirm和Cancel操作是一对反向业务操作。 3. TCC的每项操作执行动作? - Try:尝试执行操作 · 完成所有业务检查(一致性) · 预留必须业务资源(准隔离性) - Confirm:确认执行业务 · 真正执行业务 · 不做任何业务检查 · 只使用Try阶段预留的业务资源 - Cancel:取消执行业务 · 释放Try阶段预留的业务资源 4. TCC的优点? - 解决了跨应用业务操作的原子性问题,在诸如组合支付、账务拆分场景非常实用。 - TCC实际上把数据库层的二阶段提交上提到了应用层来实现,对于数据库来说是一阶段提交,规避了数据库层的2PC性能低下问题。 5. TCC的不足? - TCC的Try、Confirm和Cancel操作功能需业务提供,开发成本高。 【业务场景】 就拿用户完成订单后,需要进行支付来说,可以同时使用红包和资金账户去支付,红包和资金分别对应着不同的服务。 若使用TCC方案,则该场景过程应如下: - 下完订单后,订单状态为DRAFT,在TCC事务中TRY阶段,订单支付服务将订单状态变成PAYING,同时远程调用红包帐户服务和资金帐户服务,将付款方的余额减掉(预留业务资源); - 如果在TRY阶段,任何一个服务失败,tcc-transaction将自动调用这些服务对应的cancel方法,订单支付服务将订单状态变成PAY_FAILED,同时远程调用红包帐户服务和资金帐户服务,将付款方余额减掉的部分增加回去; - 如果TRY阶段正常完成,则进入CONFIRM阶段,在CONFIRM阶段(tcc-transaction自动调用),订单支付服务将订单状态变成CONFIRMED,同时远程调用红包帐户服务和资金帐户服务对应的CONFIRM方法,将收款方的余额增加。 【总结】 对于是否使用TCC方案,我们可以从以下几点考虑: - 是否真正有保证跨应用业务操作的原子性需求。 - 研发上能否投入资源开发相对应的TCC接口。 - 能否搞定一个稳定的、高可用的、扩展性强的TCC事务管理器。 对于TCC模型,没有在实战中接触过,博客的内容是通过查阅一些相关资料总结而来,若有不对之处,欢迎读者指正。