基于RocketMQ可靠性消息最终一致性分布式事务Demo

本实例基于 冰河《深入理解分布式事务原理与实战》中第16章案例实现。

  • 场景说明:

通过模拟商城业务中的下单扣减库存的场景:
在这里插入图片描述
提交订单时,订单服务向RocketMQ发送事务消息,RocketMQ成功接收到消息后,会向订单服务返回确认消息。此时,订单服务执行本地事务,将订单相关信息落库。若订单服务本地事务执行成功,则会向RocketMQ发送提交事务的消息,否则,则会向RocketMQ发送事务回滚的消息。
库存服务订阅RocketMQ的消息,如果收到订单确认成功的消息后,就会执行本地事务,扣减库存。库存扣减异常,可以通过MQ消息,通知订单服务,执行回滚操作。
在这里插入图片描述
整体流程如下所示:
第一步:订单微服务向RocketMQ发送Half消息。
第二步:RocketMQ向订单微服务响应Half消息发送成功。
第三步:订单微服务执行本地事务,向本地数据库中插入、更新、删除数据。
第四步:订单微服务向RocketMQ发送提交事务或者回滚事务的消息。
第五步:如果库存微服务未收到消息,或者执行事务失败,且RocketMQ未删除保存的消息数据,RocketMQ会回查订单微服务的接口,查询事务状态,以此确认是再次提交事务还是回滚事务。
第六步:订单微服务查询本地数据库,确认事务是否执行成功。
第七步:订单微服务根据查询出的事务状态,向RocketMQ发送提交事务或者回滚事务的消息。
第八步:如果第七步中订单微服务向RocketMQ发送的是提交事务的消息,则RocketMQ会向库存微服务投递消息。
第九步:如果第七步中订单微服务向RocketMQ发送的是回滚事务的消息,则RocketMQ不会向库存微服务投递消息,并且会删除内部存储的消息数据。
第十步:如果RocketMQ向库存微服务投递的是执行本地事务的消息,则库存微服务会执行本地事务,向本地数据库中插人、更新、删除数据。
第十一步:如果RocketMQ向库存微服务投递的是查询本地事务状态的消息,则库存微服务会查询本地数据库中事务的执行状态。

环境搭建:

  • 搭建RocketMQ环境:
    参考:

https://blog.csdn.net/weixin_46475802/article/details/128541293

  • 搭建JAVA环境:
    • 创建数据库:

      DROP DATABASE IF EXISTS `tx-msg-order`;
      CREATE DATABASE `tx-msg-order` charset utf8;
      DROP DATABASE IF EXISTS `tx-msg-stock`;
      CREATE DATABASE `tx-msg-stock` charset utf8;
      
    • 拉取代码:
      地址:

      https://gitee.com/Romen_Geng/tx-msg.git

    • 启动环境:

      数据库:
      在这里插入图片描述
      在这里插入图片描述

    • Postman测试:
      在这里插入图片描述
      服务日志:
      在这里插入图片描述
      在这里插入图片描述

    • 模拟订单异常:

        // 模拟订单异常
        if (Math.random() > 0) {
            throw new RuntimeException("模拟订单异常");
        }
    
    在这里插入图片描述
    订单本地事务执行失败,MQ消息对库存服务不可见。
    • 模拟库存异常:
        // 模拟库存异常
        if (Math.random() > 0) {
            throw new RuntimeException("模拟库存异常");
        }

在这里插入图片描述
在这里插入图片描述

订单需要进行自定义业务逻辑处理,否则会一直回查本地事务。

自定义订单回滚逻辑:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值