发布网友 发布时间:2022-11-27 01:18
共1个回答
热心网友 时间:2023-10-13 06:30
TCC是Try、Confirm、Cancel三个词语的缩写,要求每个分支事务执行三个操作:
预处理Try:做业务检查和资源预留
确认Confirm:做业务确认
撤销Cancel:实现回滚操作
TM首先会发起所有分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try全部成功,TM将会发起所有分支事务的confirm操作,其中,若confirm、cancel执行失败,TM会进行重试。
1)Try阶段是做业务检查(一致性)及资源预留(隔离)。
2)Confirm阶段是做确认提交,Try阶段所有分支事务执行成功开始执行confirm。
通常情况下使用TCC则认为在Confirm阶段不会出错,只要try成功,confirm一定成功。若confirm出错,则进行重试或人工处理。
3)Cancel阶段是在业务执行错误需要回滚的状态下,执行其他未失败的分支事务的取消,即预留资源的释放。
通常情况下,TCC的Cancel阶段也认为是一定成功的,若出错曾引入重试或人工处理。
以下几个框架均支持TCC全局事务,目前阿里seata拥有较大的用户基数,github的star数也是遥遥领先,后面会逐步增加seata实战源码。
在Try阶段,假设对服务A发送Try请求,由于网络原因导致网络超时,此时协调器收到网络超时的响应,需要在第二步进行cancel操作。可是服务A在Try阶段根本没有执行成功,这样就导致了数据不一致。
解决问题的关键是如何在Try阶段识别出服务A是否执行成功了,如果成功了就执行commit,如果失败了,就执行空回滚。可以增加一张分支事务记录表,记录分支事务和全局事务id,当请求超时后可以通过此表查看分支事务,执行Try则记录,没有则走空回滚。
主要出现在Try阶段。在confirm或cancel前先进行查询,通过增加一张事务状态表。
更加严谨需要增加分布式锁。
由于超时等原因,cancel比try先执行,就是悬挂问题。
解决方案增加分支事务记录表,先去查询,如果cancel已经执行,则不再执行try。