提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
TCC模式
一个分布式的全局事务,整体是两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:
- 一阶段 prepare 行为
- 二阶段 commit 或 rollback 行为
两阶段提交 的模型
TCC模式与AT模式非常相似,每阶段都是独立事务,不同的是TCC通过人工编码来实现数据恢复。需要实现三个方法:
- try:资源的检测和预留;
- confirm:完成资源操作业务;要求 try 成功 confirm 一定要能成功。
- cancel:预留资源释放,可以理解为try的反向操作。
1.流程分析
举例,一个扣减用户余额的业务。假设账户A原来余额是100,需要余额扣减30元。
阶段一( Try ):
检查余额是否充足,如果充足则冻结金额增加30元,可用余额扣除30
初始余额:
余额充足,可以冻结:
此时,总金额 = 冻结金额 + 可用金额,数量依然是100不变。事务直接提交无需等待其它事务。
阶段二(Confirm):
假如要提交(Confirm),之前可用金额已经扣减,并转移到冻结金额。因此可用金额不变,直接冻结金额扣减30即可:
此时,总金额 = 冻结金额 + 可用金额 = 0 + 70 = 70元
阶段二(Canncel):
如果要回滚(Cancel),则释放之前冻结的金额,也就是冻结金额扣减30,可用余额增加30
2.事务悬挂 和 空回滚
假如一个分布式事务中包含两个分支事务,try阶段,一个分支成功执行,另一个分支事务阻塞:
如果阻塞时间太长,可能导致全局事务超时而触发二阶段的cancel操作。两个分支事务都会执行cancel操作:
空回滚
- 要知道,其中一个分支是未执行try操作的,直接执行了cancel操作,反而会导致数据错误。
- 因此,这种情况下,尽管cancel方法要执行,但其中不能做任何回滚操作,这就是空回滚。
防悬挂
- 对于整个空回滚的分支事务,将来try方法阻塞结束依然会执行。但是整个全局事务其实已经结束了,因
- 此永远不会再有confirm或cancel,也就是说这个事务执行了一半,处于悬挂状态,这就是业务悬挂问题。此时业务应用应该要拒绝处理,返回异常。
以上问题都需要我们在编写try、cancel方法时处理。
3.总结
TCC模式的每个阶段是做什么的?
- Try:资源检查和预留
- Confirm:业务执行和提交
- Cancel:预留资源的释放
TCC的优点是什么?
- 一阶段完成直接提交事务,释放数据库资源,性能好
- 相比AT模型,无需生成快照,无需使用全局锁,性能最强
- 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库
TCC的缺点是什么?
- 有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦
- 软状态,事务是最终一致
- 需要考虑Confirm和Cancel的失败情况,做好幂等处理、事务悬挂和空回滚处理