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的理解以及思考。
来源:oschina
链接:https://my.oschina.net/u/3457546/blog/4933641