分布式事务:从理论到实践(三)

简介: TCC 服务在未收到 Try 请求的情况下收到 Cancel 请求,这种场景被称为空回滚;空回滚在生产环境经常出现,用户在实现TCC服务时,应允许允许空回滚的执行,即收到空回滚时返回成功。

接着前面两篇说,下面我们继续对 Seata 的 TCC 模式进行讨论。


TCC


原理回顾


简单回顾一下TCC的原理 参考 蚂蚁金服的博客[1]


正常事务逻辑


  1. try
  2. cancel 或 confirm


50.jpg


允许空回滚


1 未正常 try 2 执行了空 cancel


51.jpg


TCC 服务在未收到 Try 请求的情况下收到 Cancel 请求,这种场景被称为空回滚;空回滚在生产环境经常出现,用户在实现TCC服务时,应允许允许空回滚的执行,即收到空回滚时返回成功。


防悬挂控制


  1. try超时
  2. cancel成功
  3. try重试
  4. Confirm 或者 Cancel 永远不会得到执行,造成悬挂。


52.jpg


此外,除了上面这些,和AT一样,还是要注意幂等的控制


代码实现


先讲下抽象流程和注意事项


53.jpg


  • 首先定义事务接口,接口中就是你的tcc三个方法,对应代码中的prepare、commit、rollback。
  • 注意加@LocalTCC 注解(必要),适用于SpringCloud+Feign模式下的TCC
  • @TwoPhaseBusinessAction(必要) 注解try方法,name 一般写方法名就行,注意全局唯一,commitMethod对应提交方法名,rollbackMethod对应回滚方法名。
  • BusinessActionContext 就是 seata tcc 的事务上下文,用于存放 tcc 事务的一些关键数据。BusinessActionContext 对象可以直接作为 commit 方法和 rollbakc 方法的参数,Seata 会自动注入参数:


54.jpg


@BusinessActionContextParameter 该注解用来修饰 Try 方法的入参,被修饰的入参可以在 Commit 方法和 Rollback 方法中通过 BusinessActionContext 获取


55.jpg


56.jpg


我们根据 官方的例子[2]用一个业务场景串一下。


这是一个转账的操作:


接口定义:


57.jpg


在事务调用入口加入 @GlobalTransactional


58.jpg


先让扣钱参与者准备扣钱,如果失败,则回滚本地和分布式事务


看下扣钱的try方法实现:


59.jpg


再让加钱参与者准备加钱,如果失败,则回滚本地和分布式事务 看下加钱的try方法实现:


60.jpg


如果上面两步都成功,则会分别调用各自的commit方法,如果方法有异常将会重试firstAction 提交扣钱


61.jpg


secondActin 提交加钱


62.jpg


如果firstAction和secondAction的try方法有异常将会自动调用各自的rollback方法:


63.jpg


64.jpg


总结


整体来看TCC的模式编码还是比较简单的,不过还是有几点需要注意:

  • 根据业务设计好tcc的三个方法
  • 接口幂等
  • 允许空回滚 比如以订单创建举例,如果try()方法没执行,那么订单一定没创建,所以cancle方法里可以加一个判断,如果上下文中订单编号orderNo不存在或者订单不存在,直接return


if(orderNo==null || order==null){
    return;
  }


  • 防悬挂控制 参考[3]  ) 可以在二阶段执行时插入一条事务控制记录,状态为已回滚,这样当一阶段执行时,先读取该记录,如果记录存在,就认为二阶段回滚操作已经执行,不再执行try方法。
相关文章
|
1月前
|
NoSQL 关系型数据库 MySQL
分布式锁:不同实现方式实践测评
分布式锁:不同实现方式实践测评
34 0
|
1月前
|
负载均衡 监控 Dubbo
Java微服务架构设计与实践:构建可伸缩的分布式系统
【4月更文挑战第2天】微服务架构响应现代业务需求,通过拆分大型应用为独立服务实现模块化和可扩展性。Java中的Spring Boot和Dubbo等框架支持服务注册、负载均衡等功能。遵循单一职责、自治性和面向接口原则,每个服务专注特定逻辑,独立部署运行。实际项目中,如电商系统,服务按功能拆分,提升可维护性和扩展性。还需考虑服务通信、数据一致性和监控等复杂话题。Java微服务架构助力构建高效、灵活的应用,应对未来挑战。
Java微服务架构设计与实践:构建可伸缩的分布式系统
|
18天前
|
分布式计算 负载均衡 并行计算
Python 分布式计算框架 PP (Parallel Python):集群模式下的实践探索
该文介绍了使用Parallel Python (PP) 在两台物理机上构建分布式计算集群的经验。PP是一个轻量级框架,旨在简化Python代码在多处理器系统和集群中的并行执行。文中通过设置子节点的IP、端口和密钥启动PP服务器,并在主节点创建PP实例进行负载均衡。实验使用官方的质数和计算示例,显示PP在集群模式下能有效利用多台机器的多核CPU,实现计算效率的显著提升。未来,作者计划进一步研究PP在更复杂任务和大规模集群中的应用潜力。
|
25天前
|
监控 NoSQL 数据建模
使用Apache Cassandra进行分布式数据库管理的技术实践
【6月更文挑战第5天】本文探讨了使用Apache Cassandra进行分布式数据库管理的技术实践。Cassandra是一款高性能、可扩展的NoSQL数据库,适合大规模、高并发场景。文章介绍了其高可扩展性、高性能、高可用性和灵活数据模型等核心特性,并详细阐述了环境准备、安装配置、数据建模与查询以及性能优化与监控的步骤。通过本文,读者可掌握Cassandra的运用,适应不断增长的数据需求。
|
16天前
|
存储 监控 负载均衡
Zookeeper 详解:分布式协调服务的核心概念与实践
Zookeeper 详解:分布式协调服务的核心概念与实践
15 0
|
1月前
|
Cloud Native 数据管理 关系型数据库
【阿里云云原生专栏】云原生数据管理:阿里云数据库服务的分布式实践
【5月更文挑战第21天】阿里云数据库服务在云原生时代展现优势,应对分布式数据管理挑战。PolarDB等服务保证高可用和弹性,通过多副本机制和分布式事务确保数据一致性和可靠性。示例代码展示了在阿里云数据库上进行分布式事务操作。此外,丰富的监控工具协助用户管理数据库性能,支持企业的数字化转型和业务增长。
197 1
|
1月前
|
分布式计算 并行计算 Java
【分布式计算框架】 MapReduce编程初级实践
【分布式计算框架】 MapReduce编程初级实践
38 2
|
1月前
|
存储 Java 分布式数据库
【分布式计算框架】HBase数据库编程实践
【分布式计算框架】HBase数据库编程实践
36 1
|
1月前
|
分布式计算 数据可视化 Hadoop
【分布式计算框架】HDFS常用操作及编程实践
【分布式计算框架】HDFS常用操作及编程实践
28 1
|
1月前
|
存储 大数据 Apache
深入理解ZooKeeper:分布式协调服务的核心与实践
【5月更文挑战第7天】ZooKeeper是Apache的分布式协调服务,确保大规模分布式系统中的数据一致性与高可用性。其特点包括强一致性、高可用性、可靠性、顺序性和实时性。使用ZooKeeper涉及安装配置、启动服务、客户端连接及执行操作。实际应用中,面临性能瓶颈、不可伸缩性和单点故障等问题,可通过水平扩展、集成其他服务和多集群备份来解决。理解ZooKeeper原理和实践,有助于构建高效分布式系统。