什么是 TCC?
TCC 是 Try-Confirm-Cancel 的缩写,它是一种分布式事务解决方案,采用了基于业务逻辑的补偿机制,将整个分布式事务分解为若干个子事务,每个子事务都有一个 try、confirm 和 cancel 三个操作,通过这些操作来实现分布式事务的执行和回滚

TCC 事务包括三部分
- Try:在 try 阶段,参与者尝试执行事务,并对全局事务预留资源。如果 try 成功就会返回成功标识,反之失败会失败标识。
- Confirm:如果所有的参与者 try 阶段都成功,协调者就会通知参与者提交事务。那么就要执行 confirm 阶段,与者提交本地事务,释放全局事务预留资源
- Cancel:如果任何一个参与者在try阶段执行失败,则协调者通知所有参与者回滚事务。那么就要执行cancel阶段。
TCC 事务的例子
以下是一个简单的 TCC 事务的例子,假设有一个转账服务,需要从 A 账户中转移到 B 账户中 100 元、C 账户中200 元:
- Try 阶段:转账服务首先冻结 A 账户中的 300 元
- Confirm 阶段:所有的 try 操作都成功,转账服务解除 A 账户冻结的 300 元,并开始对 B、C 转账
- Cancel 阶段:如果 try 过程中,某个转账事务执行失败,那么将执行解冻,将 300 元解冻。如果在 confirm 过程中,A->C 的转账成功,但是 A->B 的转账失败,则再操作一次 C->A 的转账,将钱退回去。
TCC 事务方案的优点和缺点
优点:
- 灵活性:TCC适用于不同类型的业务场景,例如账户转账、库存扣减等,能够根据业务逻辑实现精细的事务控制。
- 高可用性:TCC使用分布式锁来保证分布式事务的一致性,即使其中一个节点出现故障,也不会影响整个系统的运行。
- 可扩展性:TCC采用分阶段提交的方式,支持横向扩展,可以适应更多的并发访问和业务场景
- 性能:TCC相对于2PC来说,具有更好的性能表现
缺点:
- 实现复杂、业务代码侵入性:TCC 需要实现 Try、Confirm 和 Cancel 三个操作,每个操作都需要针对不同的业务场景实现正确的业务逻辑和补偿机制,代码实现比较复杂,对业务代码有一定的侵入性。
- 存在悬挂事务问题:TCC 的实现方式存在悬挂事务的问题,即在执行过程中可能会有部分子事务成功,而其他子事务失败,导致整个事务无法回滚或提交。
- 空回滚问题:TCC 中的 Ty 过程中,有的参与者成功了,有的参与者失败了,这时候就需要所有参与者都执行Cancel,这时候,对于那些没有 Try 成功的参与者来说,本次回滚就是一次空回滚。需要在业务中做好对空回滚的识别和处理,否则就会出现异常报错的情况,甚至可能导致 Cancel 一直失败,最终导致整个分布式事务失败。
悬挂事务和空回滚解决方案
悬挂事务和空回滚这两个问题处理不好,都可能会导致一个分布式事务没办法保证最终一致性。有一个办法,可以一次性的解决以上两个问题,那就是–引入分布式事务记录表。
分布式事务记录表主要有 tx_id 事务id,还有 status 状态。
空回滚解决:当一个参与者接到一次 Cancel 请求的时候,先去 distribute transaction 表中根据 tx_id 查询是否有 try 的记录,如果没有,则进行一次空回滚即可。并在 distribute transaction 中创建一条记录,状态标记为cancel。
事务悬挂解决:当一个参与者接到一次 Try 请求的时候,先去 distribute transaction 表中根据 tx_id 查询是否有记录,如果当前存在,并且记录的状态是 cancel,则拒绝本次 try 请求。
Confirm 或者 Cancel 失败了怎么办
Confirm 失败
1、重试
种常见的策略是重试 Confirm 操作。这通常适用于由于临时问题(如网络延迟、服务短暂不可用等)导致的失败。在重试之前,可以设定一个延迟或等待一段时间,然后再次尝试 Confirm 操作。通常,会设置重试次数的上限,以避免无限重试。
这个方案用的是最多的,之所以可以这么做,主要是因为在 Try 的过程中已经锁定了资源,那么在 Confirm 的时候,大概率是可以成功,而如果 Confirm 失败就执行 Cancel,就会导致可能只是因为网络原因导致的时候就使得整个事务都Cancel了,而且这时候如果 Cancel 再失败怎么办呢?整个方案就会变得更加复杂了。
2、执行 Cancel 操作
如果重试 Confirm 操作依然失败,或者系统确定 Confirm 无法成功,下一步是执行 CanceI 操作。Cancel 阶段的目的是撤销在 Try 阶段预留的所有资源,确保系统回到事务开始前的状态。这是一种典型的回滚操作,用于处理事务失败的情况。
3、日志记录和异常监控
在Confirm失败的情况下,重要的是记录详细的错误日志和监控异常。这可以帮助系统管理员或开发人员分析为什么Confirm操作失败,并采取相应的改进措施。此外,日志可以帮助在事后定位问题的根源。
4、人工干预
在某些复杂或重要的事务中,如果自动化的重试和回滚失败,可能需要人工干预,这涉及到系统管理员或运维团队直接介入,手动处理故障和确保系统的一致性与稳定性。
Cancel 失败
般有以下几种处理手段,和 Confirm 也差不多,无非就是报警、重试、人工干预。
- 记录日志&发送报警:将错误信息记录下来,方便后续分析和处理。并及时通知相关人员进行处理
- 自动重试:在一定程度上,可以通过自动重试的方式尝试多次执行 Cancel 操作,直到成功为止。
- 人工干预:如果重试多次还是不成功,可以报警,然后进行人工干预,可以尝试手动执行 Cancel 操作或者进行数据修复等。
787

被折叠的 条评论
为什么被折叠?



