作者:ptti

来源:恒生LIGHT云社区

经过前面的文章《seata入门介绍与seata-service布置与验证》,咱们对seata已经有一个大体的知道,而且也了解到seata分布式业务AT形式,今天咱们介绍SEATA分布式业务结构中TCC业务结构。打算从原理、实践原型演示、推荐的应用场景、注意事项等这几个维度去介绍TCC分布式业务。

首先介绍一下TCC,关于TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年宣布的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。

TCC作为一种与渠道无关的抽象的开放的计划,有很多厂商有自己的实践。已知比较流行的有开源结构有ByteTCC, SEATA,恒生电子也有自己的TCC实现。了解SEATA TCC原理推荐阅读以下两个材料:

SEATA的官方介绍:SEATA.io/zh-cn/docs/…

蚂蚁金服相关开发者共享:www.bilibili.com/video/BV1pK…

关于TCC的解释:

  • Try阶段:测验履行,完成一切业务查看(一致性),预留有必要业务资源(准阻隔性)
  • Confirm阶段:承认履行真实履职业务,不作任何业务查看,只运用Try阶段预留的业务资源,Confirm操作满意幂等性。要求具有幂等规划,Confirm失利后需求进行重试。
  • Cancel阶段:取消履行,开释Try阶段预留的业务资源 Cancel操作满意幂等性Cancel阶段的反常和Confirm阶段反常处理计划基本上一致。

对TCC的了解概括如下:

  • 依据Confirm 与 Cancel使命履行必定成功的假设下,TCC仍然是一个2PC协议。
  • 在分布式环境下,它没有供给一个大局的锁的机制去操控资源竞争,仅是约定一个反常时处理回滚操作的流程。

原型演示:

本文触及demo 依据Springcloud + Feign。选用Spring Boot工程,整合Spring Cloud Feign,业务数据库选用的Mysql8.0。

1、业务DB初始化,运用相关脚本构建业务db。

seata分布式事务TCC模式介绍及推荐实践

2、maven project布置,包括三个业务模块:account用户中心,order订单中心,storage库存中心。

seata分布式事务TCC模式介绍及推荐实践

order是全体业务的进口。

seata分布式事务TCC模式介绍及推荐实践

要害依赖

  • spring-cloud-alibaba-SEATA-x.x.x.RELEASE-sources.jar SEATA与 Spring Cloud 原生组件(Feign, Hystrix …)适配与集成。
  • SEATA-all-x.x.x.jar SEATA 的中心业务逻辑。
  • SEATA-spring-boot-starter.x.x.x.jar 与spring boot的集成。

业务一致性中心接口

OrderTccAction.java
AccountTccAction.java
StorageTccAction.java

seata分布式事务TCC模式介绍及推荐实践

3、全体逻辑如下图:

seata分布式事务TCC模式介绍及推荐实践

4、初始化数据信息

账户余额表

seata分布式事务TCC模式介绍及推荐实践

订单数据表

seata分布式事务TCC模式介绍及推荐实践

库存信息表

seata分布式事务TCC模式介绍及推荐实践

场景演示1:演示一次正常下单成功进程

seata分布式事务TCC模式介绍及推荐实践

恳求回来正常

seata分布式事务TCC模式介绍及推荐实践

数据库符合预期

seata分布式事务TCC模式介绍及推荐实践
seata分布式事务TCC模式介绍及推荐实践
seata分布式事务TCC模式介绍及推荐实践

场景演示2:演示一次库存缺乏下单失利进程

seata分布式事务TCC模式介绍及推荐实践

注:撤销订单的进程可能是异步完成;

中心代码:

seata分布式事务TCC模式介绍及推荐实践

成果演示

seata分布式事务TCC模式介绍及推荐实践

数据验证,订单并未生成

seata分布式事务TCC模式介绍及推荐实践

以上,演示结束,当然能够规划更多场景进行验证,这儿不再展开。

关于seata的TCC形式的一些注意事项与推荐实践

1、关于空回归,悬挂和幂等问题,现在TCC形式下,业务同学有必要自己处理这3个问题。怎么规划业务查询表去处理这3个问题是具有一定的技能难度的。例如选用了一个大局的静态的ConcurrentHashMap ResultHolder.map 作为业务查询表处理了幂等问题,供参阅。需求到网上查找更多相关材料学习。当然SEATA现在已经实现了一个通用的业务查询表功能,结构有能力自己去处理这3个问题。

2、二阶段的动作有必要成功:一阶段成功后,二阶段的Confirm与Cancel 动作有必要成功是TCC形式的约定与条件。开发者需求依据自己实践的业务场景,去判断相关的业务逻辑是放在Try中还是放在Confirm中。 在示例代码中存在一个比较典型的业务区分的办法,即在Try中操作frozen 字段确定账户金额/产品库存,在Confirm中操作used字段去正式扣款/扣库存。如果没有frozen字段,那么扣款/扣库存的动作应该放置于Try办法中而不是Confirm办法中。

3、默认不支撑并发多线程。

依据SEATA的源码剖析与实践代码验证;TCC形式自身对多线程并发履行支撑有限。

如果拓荒其他线程履行使命调用(无论是本地调用,还是RPC/HTTP长途调用),不会加入本地大局业务。

依据此问题,已经在社区有相关实践经验的开发者承认,经过自己获取xId加入到相关线程的ThreadLocalMap中就能够把当时线程履行的使命join到大局业务中;

处理了本地调用场景的条件下,理论上长途调用的场景不需求再做额定处理,因为结构会在RPC/Http发起之前拦截恳求,将相关的大局业务信息从Thread中获取,写入到恳求中。

下面这个项目值得参阅github.com/caohdgege/s…一下,他一定程度上处理了多线程场景的问题,但是尚未验证。因时刻有限,这儿并未进一步承认该计划是否100%准确无误。

4、TCC无默认数据阻隔性。TCC经过约定了一个反常回滚的调用流程,仅仅是处理了分布式环境下业务的原子性问题。无论是分布式环境下,还是单机环境下的数据阻隔性问题,完全需求业务同学自己考虑。在本Demo中能够看到Try or Confirm办法大多会被@Transactional 要害字修饰;单库的ACID性还需求依赖DB自身供给。

5、二阶段(Confirm与Cancel)可能会异步处理。TCC计划比较适合高并发的业务场景。依据confirm 与 rollback操作必定成功的假设条件,二阶段异步处理会极大提升高峰期业务的性能。比如本demo中的示例,客户落单后能够先只是冻住账户金额,并不直接划拨金钱,比及业务高峰期结束,再约定一个时刻(可能时某个定时使命)统一划拨,然后到达削峰的效果。

到此seata分布式业务TCC形式原理和运用共享完成。


想向技能大佬们多多取经?开发中遇到的问题何处讨论?怎么获取金融科技海量资源?

恒生LIGHT云社区,由恒生电子建立的金融科技专业社区渠道,共享实用技能干货、资源数据、金融科技职业趋势,拥抱一切金融开发者。