目前市场上的TCC框架有很多,比如以下几种(以下数据采集日为2020年07月05日):
名称 | 地址 | star数量 |
---|---|---|
tcc-transaction | https://github.com/changmingxie/tcc-transaction | 4785 |
Hmily | https://github.com/yu199195/hmily | 2835 |
ByteTCC | https://github.com/liuyangming/ByteTCC | 2408 |
EasyTransaction | https://github.com/QNJR-GROUP/EasyTransaction | 2094 |
作为实战的演示程序,我们的目标是理解TCC的原理以及事务协调运作的过程,因此更倾向于轻量级易于理解的框架,所以本次案例使用Hmily框架。
1. Hmily框架介绍
官网地址:https://dromara.org/website/zh-cn/docs/hmily/index.html
Hmily是一个高性能分布式事务TCC开源框架。基于Java语言来开发(JDK1.8),支持Dubbo,Spring Cloud等
RPC框架进行分布式事务。它目前支持以下特性:
- 支持嵌套事务(Nested transaction support)。
- 支持SpringBoot-starter 项目启动,使用简单。
- RPC框架支持 : dubbo、motan、springcloud。
- 采用Aspect AOP 切面思想与Spring无缝集成,天然支持集群。
- RPC事务恢复,超时异常恢复等。
Hmily利用AOP对参与分布式事务的本地方法与远程方法进行拦截处理,通过多方拦截,事务参与者能透明的
调用到另一方的Try、Confirm、Cancel方法;传递事务上下文;并记录事务日志,酌情进行补偿,重试等。
Hmily实现的TCC服务与普通的服务一样,只需要暴露一个接口,也就是它的Try业务。Confirm/Cancel业务
逻辑,只是因为全局事务提交/回滚的需要才提供的,因此Confirm/Cancel业务只需要被Hmily TCC事务框架
发现即可,不需要被调用它的其他业务服务所感知。
2. Hmily实现TCC事务
2.1 业务说明
下面我们通过Hmily实现分布式事务来模拟两个账户的转账交易过程。交易过程是:张三给李四转账指定金额。
2.2 开发环境
- 数据库:
MySQL-5.6
- 微服务框架:
spring-boot-2.2.2.RELEASE
、spring-cloud-Hoxton.SR1
、hmily-springcloud-2.0.6.RELEASE
2.2.1 启动程序
源码地址:https://gitee.com/anbang713/distributed-transaction-study
启动程序之前,我们需要使用源码工程中对应的sql脚本创建相对应的数据库和表,以及插入测试数据。
(1)首先我们要启动registry-server
服务注册中心;
(2)分别启动hmily-demo-bank1
和hmily-demo-bank2
微服务。
2.3 核心代码
(1)引入hmily
依赖
<dependency>
<groupId>org.dromara</groupId>
<artifactId>hmily-springcloud</artifactId>
<version>2.0.6-RELEASE</version>
</dependency>
(2)配置hmily
org:
dromara:
hmily:
serializer: kryo
recoverDelayTime: 30
retryMax: 30
scheduledDelay: 30
scheduledThreadMax: 10
repositorySupport: db
started: true
hmilyDbConfig:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/hmily?useUnicode=true
username: root
password: Anbang713
(3)新增配置类接收hmily
的配置信息,并创建HmilyTransactionBootstrap
bean,同时在配置类上加上@EnableAspectAutoProxy
注解。
(4)启动类上增加org.dromara.hmily
的扫描项。
(5)在业务实现类添加try
、confirm
、cancel
方法,并在try
方法上使用@Hmily
注解(具体见源码)。
2.4 核心逻辑
(1)hmily-demo-bank1
的AccountInfoServiceImpl
的逻辑:
try:
try幂等校验
try悬挂处理
检查余额是够扣减金额
扣减金额
confirm:
空
cancel:
cancel幂等校验
cancel空回滚处理
增加可用余额
(2)hmily-demo-bank2
的AccountInfoServiceImpl
的逻辑:
try:
空
confirm:
confirm幂等校验
正式增加金额
cancel:
空
3. 测试场景
(1)张三向李四转账成功
http://localhost:9011/bank1/transfer?amount=1
(2)李四事务失败,张三事务回滚成功(停止hmily-demo-bank2
服务)
http://localhost:9011/bank1/transfer?amount=3
(3)张三事务失败,李四事务回滚成功
http://localhost:9011/bank1/transfer?amount=2
4. 总结
如果拿TCC事务的处理流程与2PC两阶段提交做比较,2PC通常都是在跨库的DB层面,而TCC则在应用层面的处
理,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势在于,可以让应用自己定义数据操作的粒度,使
得降低锁冲突、提高吞吐量成为可能。
而不足之处则在于对应用的侵入性非常强,业务逻辑的每个分支都需要实现try、confirm、cancel三个操作。此外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。