分布式事务(二):TCC模型

我的未来我决定 提交于 2021-01-30 00:55:43

TCC介绍

TCC概念由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出,在该论文中,TCC还是以Tentative-Confirmation-Cancellation命名。
正式以Try-Confirm-Cancel作为名称的是Atomikos公司。

认识TCC

  • TCC区别于XA事务,是一种用于分布式系统中跨服务的事务管理模型;此模型通过管理服务,而不是资源管理器实现。
  • TCC是一种补偿型事务,也是一种柔性事务(存在中间态),该模型要求应用服务提供 try、confirm、cancel 三个接口,分别对应资源预留、操作确认、操作取消业务逻辑。
  • 在TCC模型中,如果事务可以提交,则完成对预留资源的确认(调用confirm),如果事务要回滚,则释放预留的资源(调用cancel)。
  • TCC中try、confirm、cancel接口需要考虑幂等。
  • TCC区别于XA模型以及JAVA中的JTA接口,主要依赖业务代码实现;不用考虑框架、资源管理器、通信协议的支持和规范。

TCC与XA对比

  • TCC中对资源的锁是基于业务代码实现(这里的锁意思就是try接口中的预留动作),而XA基于数据库的序列化隔离级别实现。
  • TCC可以解决XA中单点以及并发的问题,可以实现业务资源更细粒度的控制,从而提升并发量。
  • XA在应用框架中实现,对业务代码没有入侵;TCC中try、confirm、cancel接口完全交由业务实现,对业务入侵较大,对程序设计和开发水平有一定要求。
  • 关于XA的数据一致性问题,TCC中可以进行自动补偿或人工处理等手段介入。
关于数据一致性:理论上来说,cancel和confirm接口也可能出现问题,假设这个问题是重试无法解决的,只有通过人工介入处理。

举个栗子

假设我们要实现一个转账场景,我们先设想一下TCC模型如何在代码中实现:

首先有三个独立的服务:transfer(转账入口)、bank1(转出银行)、bank2(转入银行)。
其中bank1、bank2都提供TCC中三个接口,transfer提供服务入口;并且进行try-catch-finally代码块:

1.在transfer服务方法开始,初始化全局事务ID(可以理解为某一次请求的唯一标志)、操作日志记录等。

2.在try代码块中分别调用bank1、bank2的try接口对转账金额进行锁定。
	2.1记录日志。
	2.2判断返回状态,状态不对抛出异常。
	2.3记录操作状态 tryStatus=true/false(bank1和bank2有一个返回的信息不对就是false)。
	2.4如果tryStatus=false,则可以抛出异常。

3.在catch代码块中,分别调用bank1、bank2的cancel接口。
	3.1记录日志。
	3.2判断调用cacel接口的状态,如果调用出错(网络错误等)需要自动重试,或者人工处理。

4.在finally代码块中。
	4.1记录日志
	4.2判断tryStatus=true;说明bank1/2都调用成功,这调用bank1、bank2的confirm接口。
	4.22判断调用confirm接口的状态(跟3.2一样),如果调用出错(网络错误等)需要自动重试,或者人工处理。

5.其他异常,比如说transfer服务代码走到一半机器重启了怎么办?
	5.1借助第一步中的日志记录,进行自动重试或者人工介入。

TCC需要注意什么?

首先读一下官方资料资料:atomikos官方发布的关于跨服务TCC解决方案

  • confirm、cancel接口的幂等。
  • 是否考虑事务过期,有没有统一的回滚协调服务,还是子服务放本身也要有自动回滚机制。
  • 完备的操作日志,应对宕机、网络故障等情况下,可实现自动补偿,或者人工介入处理。

市面上的TCC框架

实现简单的TCC本身不需要使用任何框架,毕竟TCC只是一种模型,且严重依赖于业务代码实现。

但是要综合考虑到并发能力、日志、幂等、重试等多种因素,市面上有多个框架进行了封装;一下是我个人的对比。

名称 特点 stars
tcc-transaction 开源时间最长;框架本身不支持幂等、性能相对较慢(大字段记录操作日志且频繁更改);文档简单;项目中好多XML 4.9k
hmily 日志异步提升并发(有丢失风险);支持TCC、TAC(自动生成回滚SQL)方案;框架本身不支持幂等;文档健全 3.4k
byteTCC 兼容JTA规范;支持框架幂等;文档一般 2.5k
easyTranscation 日志同步并优化IO;支持框架幂等;文档一般 2.2k

这里有个easyTranscation作者发表的 TCC框架对比 有需要可以参考下。

TCC框架在spring boot中的应用

上面列举了几个TCC框架,个人对比一段时间发现hmily文档比较健全,并且有spring cloud feign直接调用的案例,所以用这个来进行测试。

spring boot with hmily TCC
有需要的同学请一定看一下readMe,里面有一些说明,这个样例最终其实是失败的,由于时间关系不想深入研究框架,只是用这个案例来作为TCC的理解以及思考。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!