分布式事务解决方案TCC

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

什么是TCC事务

TCC是Try、Confirm、Cancel三个词语的缩写,要求每个分支事务执行三个操作:
预处理Try:做业务检查和资源预留
确认Confirm:做业务确认
撤销Cancel:实现回滚操作

TM首先会发起所有分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try全部成功,TM将会发起所有分支事务的confirm操作,其中,若confirm、cancel执行失败,TM会进行重试。

image.png

image.png

TCC分为三个阶段:

1)Try阶段是做业务检查(一致性)及资源预留(隔离)。
2)Confirm阶段是做确认提交,Try阶段所有分支事务执行成功开始执行confirm。
通常情况下使用TCC则认为在Confirm阶段不会出错,只要try成功,confirm一定成功。若confirm出错,则进行重试或人工处理。
3)Cancel阶段是在业务执行错误需要回滚的状态下,执行其他未失败的分支事务的取消,即预留资源的释放。
通常情况下,TCC的Cancel阶段也认为是一定成功的,若出错曾引入重试或人工处理。\

TCC的实现方案

以下几个框架均支持TCC全局事务,目前阿里seata拥有较大的用户基数,github的star数也是遥遥领先,后面会逐步增加seata实战源码。

名称 github
tcc-transaction github.com/changmingxi…
LCN github.com/codingapi/t…
Alibaba Seata github.com/seata/seata
Hmily github.com/yu199195/hm…
ByteTCC github.com/liuyangming…

TCC的空回滚解决了什么问题?

在Try阶段,假设对服务A发送Try请求,由于网络原因导致网络超时,此时协调器收到网络超时的响应,需要在第二步进行cancel操作。可是服务A在Try阶段根本没有执行成功,这样就导致了数据不一致。

解决问题的关键是如何在Try阶段识别出服务A是否执行成功了,如果成功了就执行commit,如果失败了,就执行空回滚。可以增加一张分支事务记录表,记录分支事务和全局事务id,当请求超时后可以通过此表查看分支事务,执行Try则记录,没有则走空回滚。

TCC如何解决幂等问题?

主要出现在Try阶段。在confirm或cancel前先进行查询,通过增加一张事务状态表。

更加严谨需要增加分布式锁。

TCC如何解决悬挂问题?

由于超时等原因,cancel比try先执行,就是悬挂问题。

解决方案增加分支事务记录表,先去查询,如果cancel已经执行,则不再执行try。


如果对朋友们有帮助,帮忙点赞关注下啊,感谢!!!

「欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边,抽奖详情见活动文章」