SpringBoot整合RocketMq实现分布式事务

 更新时间:2024年11月06日 10:33:39   作者:我是小趴菜  
这篇文章主要为大家详细介绍了SpringBoot整合RocketMq实现分布式事务的相关知识,文中的示例代码讲解详细,有需要的小伙伴可以参考一下

大家好,今天我们继续分布式事务的学习,之前我们已经实战了

springboot整合Atomikos

springboot整合Himly 

来实现分布式事务,今天我们继续学习springboot整合RocketMq来实现分布式事务

MQ实现分布式事务原理

RocketMq提供了事务消息,要实现分布式事务主要还是利用它的事务消息

  • 1:服务A首先会发送一条半事务的消息到MQ,此时服务接收方还是无法消费这条消息的
  • 2:半事务消息发送成功之后,服务A开始执行本地业务逻辑
  • 3:服务A执行完本地业务之后,提交事务,事务提交成功之后,MQ这条半事务消息就会变成原始可消费的消息
  • 4:服务接收方这时候就可以消费到这条消息,继续执行后续业务了

那么在这整个过程中可能会出现的异常有哪些呢?

1:半事务消息发送失败

如果半事务消息发送失败,那么服务A就不会继续执行接下来的业务了,整个流程会直接退出

2:本地事务提交成功,发送COMMIT消息失败

服务A事务提交之后,需要发送一条消息告诉MQ,这条半事务消息可以消费了,但是这时候,COMMIT消息发送失败了,那么这条消息就还是处于半事务状态,所以MQ会进行回查

回查服务A这个事务是否成功了,如果成功了,就会发送回查结果,如果本地事务成功了,那么回查就会发送COMMIT消息,这条消息重新设置为可消费状态

实战

服务-A

@Transactional(rollbackFor = Exception.class)
@Override
public String mqInsert(Test test) {

    //本地服务调用
    testDao.insert(test);

    //发送半事务消息
    //Test是我们本地需要保存的一个对象
    Message<String> message = MessageBuilder.withPayload(JSONObject.toJSONString(test)).build();
    rocketMQTemplate.sendMessageInTransaction("test-topic", message, null);

    return "success";
}
@RocketMQTransactionListener
public class TransactionMqListener implements RocketMQLocalTransactionListener {

    @Resource
    private TestDao testDao;

    //执行本地事务
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        //获取半事务消息
        Test test = JSONObject.parseObject(new String((byte[]) message.getPayload()), Test.class);
        System.out.println("test | executeLocalTransaction | 消息是:" + JSONObject.toJSONString(test));
        
        //根据id查询该记录是否保存成功了
        Test testExist = testDao.queryById(test.getId());
        if(testExist == null) {
            //说明本地事务提交失败了,需要回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        
        //本地事务提交成功
        return RocketMQLocalTransactionState.COMMIT;
    }

    //事务回查
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        Test test = JSONObject.parseObject(new String((byte[]) message.getPayload()), Test.class);
        System.out.println("test | checkLocalTransaction | 消息是:" + JSONObject.toJSONString(test));
        
        //还是根据id去查询记录
        Test testExist = testDao.queryById(test.getId());
        if(testExist == null) {
            //不存在,说明本地事务提交失败,回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        
        //本地事务提交成功了
        return RocketMQLocalTransactionState.COMMIT;
    }
}

服务B

@Component
@RocketMQMessageListener(topic = "test-topic",consumerGroup = "cpy-consumer-group")
public class CpyListener implements RocketMQListener<String> {


    //消息监听
    @Override
    public void onMessage(String s) {
        System.out.println("cpy服务收到消息:" + JSONObject.toJSONString(s));
    }
}

测试

我们先把这里的状态改成 UNKNOWN,来模拟本地事务提交失败的场景,来验证事务回查的效果

发送事务消息之后,我们这里是UNKNOWN状态,所以没有提交成功

此时服务-B也没有消费到消息

过了一会,MQ事务消息进行回查,此时因为数据库已经存在这条记录了,所以直接COMMIT

这时候服务消费方也成功消费到消息了

到此这篇关于SpringBoot整合RocketMq实现分布式事务的文章就介绍到这了,更多相关SpringBoot RocketMq分布式事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中List集合去除重复数据的方法汇总

    Java中List集合去除重复数据的方法汇总

    这篇文章主要给大家介绍了关于Java中List集合去除重复数据的方法,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • java 单例的五种实现方式及其性能分析

    java 单例的五种实现方式及其性能分析

    这篇文章主要介绍了java 单例的五种实现方式及其性能分析。的相关资料,需要的朋友可以参考下
    2017-07-07
  • MyBatis直接执行SQL的工具SqlMapper

    MyBatis直接执行SQL的工具SqlMapper

    今天小编就为大家分享一篇关于MyBatis直接执行SQL的工具SqlMapper,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • SpringBoot2.0集成WebSocket实现后台向前端推送信息

    SpringBoot2.0集成WebSocket实现后台向前端推送信息

    这篇文章主要介绍了SpringBoot2.0集成WebSocket实现后台向前端推送信息,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Jackson自定义序列化反序列化注解加解密字段详解

    Jackson自定义序列化反序列化注解加解密字段详解

    这篇文章主要介绍了Jackson自定义序列化反序列化注解加解密字段详解,一些场景中,数据库字段用于存储json格式数据,处于安全的考虑,该json数据中,某些敏感信息字段需要做加密存储,例如身份证号、手机号等,需要的朋友可以参考下
    2023-11-11
  • Java Chassis3熔断机制的改进路程技术解密

    Java Chassis3熔断机制的改进路程技术解密

    这篇文章主要介绍了Java Chassis 3技术解密之熔断机制的改进路程实例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Java添加Word文本水印和图片水印

    Java添加Word文本水印和图片水印

    这篇文章主要介绍了Java添加Word文本水印和图片水印,文章图文讲解的很清晰,有对于这方面不懂得同学可以学习下
    2021-02-02
  • Java 遍历list和map的方法

    Java 遍历list和map的方法

    这篇文章主要介绍了Java 遍历list和map的方法,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-12-12
  • Collections.shuffle()方法实例解析

    Collections.shuffle()方法实例解析

    这篇文章主要介绍了Collections.shuffle()方法实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • java中用数组实现环形队列的示例代码

    java中用数组实现环形队列的示例代码

    这篇文章主要介绍了java中用数组实现环形队列的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04

最新评论