RocketMQ——事务消息

事务消息就是事务里参杂着发消息的动作

如果一个事务里牵扯到发消息的操作,那么一旦消息被消费了,想要回滚,这时就变的很难

在这里插入图片描述
所以在没有commit的时候,消息只会暂时发送存在broker不会被消费,当commit成功的时候,在MQ中会将这个消息设置为真正可用,这时comusmer才会消费消息,如果执行的是rollback,在MQ中就会把这个消息撤回(就是两阶段提交的机制)

下面是事务消息执行的顺序图
在这里插入图片描述

HFMessage半消息可以为一种向broker发送的标记,与真正的消息内容完全没有关系,仅用于在broker维持该消息的状态,到底消息是可用还是不可用。

请结合以下具体代码理解上述图文

import org.apache.rocketmq.client.producer.*;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.common.RemotingHelper;

/**
 * RocketMQ——事务消息
 *
 * @author Song X.
 * @date 2020/03/04
 */
public class Producer {

    public static void main(String[] args) throws Exception {
        TransactionMQProducer producer = new TransactionMQProducer("TransactionGroup1");
        producer.setNamesrvAddr("192.168.255.131:9876");
        
        producer.setTransactionListener(new TransactionListener() {
            /**
             *  这是producer执行的本地事务
             *  begin transaction:
             *      这里面的方法应该是同步的按顺序执行
             *      a()
             *      b()
             *      c() -> producer发消息
             *      d()
             *  end transaction
             * 上面的方法应使用try-catch,若发生异常则return ROLLBACK_MESSAGE
             * 若全部成功用COMMIT_MESSAGE
             *
             *      try{
             *          a()
             *          b()
             *          c()
             *          d()
             *      } catch () {
             *          return LocalTransactionState.ROLLBACK_MESSAGE
             *      }
             *      return LocalTransactionState.COMMIT_MESSAGE
             *
             * 在这个方法中一搬不用UNKNOWN
             *
             * @param msg 就是producer send的消息
             * @param arg
             * @return  LocalTransactionState.COMMIT_MESSAGE 表示执行事务成功,确认提交
             *          LocalTransactionState.ROLLBACK_MESSAGE 表示回滚消息,broker端删除半消息(HFMessage)
             *          LocalTransactionState.UNKNOWN 表示为未知状态,等待broker回调查看
             */
            public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
                System.out.println("------executeLocalTransaction------");
                System.out.println("msgBody: " + new String(msg.getBody()));
                //transactionId就是messageId
                System.out.println("msgTransactionID: " + msg.getTransactionId());

                return LocalTransactionState.UNKNOW;
            }

            /**
             * 这是broker执行的回调函数
             * Broker端回调检查本地事务的执行状态,也就是检查executeLocalTransaction方法的执行情况
             *
             * if(...){
             *
             *     ... //如果检查了XXX,表示事务成功了
             *     return LocalTransactionState.COMMIT_MESSAGE;
             *
             * } else if(...) {
             *
             *     ... //如果检查了XXX,表示可能executeLocalTransaction还在执行,等会回来再检查
             *     return LocalTransactionState.UNKNOWN
             *
             * } else {
             *
             *     //事务执行失败了,回滚,回滚的是HFMessage
             *     return LocalTransactionState.ROLLBACK_MESSAGE
             *
             * }
             *
             * @param msg 就是producer send的消息
             * @return LocalTransactionState.COMMIT_MESSAGE;
             */

            public LocalTransactionState checkLocalTransaction(MessageExt msg) {
                System.out.println("------checkLocalTransaction------");
                System.out.println("msgBody: " + new String(msg.getBody()));
                //transactionId就是messageId
                System.out.println("msgTransactionID: " + msg.getTransactionId());

                return LocalTransactionState.UNKNOW;
            }
        });


        producer.start();

        Message msg = new Message("myTransaction","TagA", "事务消息测试".getBytes(
                RemotingHelper.DEFAULT_CHARSET
        ));

        TransactionSendResult transactionSendResult = producer.sendMessageInTransaction(msg, null);
        System.out.println("transactionSendResult: " + transactionSendResult);


  //      producer.shutdown();


    }
}

可在两个函数中都是用UNKNOWN观察checkLocalTransaction函数的回调运行机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在SpringBoot中整合RocketMQ发送事务消息的步骤如下: 首先,定义一个生产者类,使用@Component注解将其标记为一个组件,并使用@Autowired注解注入RocketMQTemplate实例。在该类中,可以编写一个sendMsg方法来发送消息。该方法接受两个参数,分别是topic和msg,使用MessageBuilder构建一个消息对象,并通过rocketMQTemplate的sendMessageInTransaction方法发送消息。需要注意的是,该方法的第一个参数要与@RocketMQTransactionListener注解中的txProducerGroup属性保持一致。\[1\] 其次,定义一个消费者类,使用@Component和@RocketMQMessageListener注解将其标记为一个组件,并指定topic和consumerGroup。该类需要实现RocketMQListener接口,并实现其中的onMessage方法,用于处理接收到的消息。\[2\] 最后,在引导类中使用@SpringBootApplication注解标记该类为Spring Boot应用程序的入口,并在main方法中调用SpringApplication的run方法启动应用程序。\[3\] 通过以上步骤,就可以在SpringBoot中整合RocketMQ发送事务消息了。 #### 引用[.reference_title] - *1* *2* *3* [springboot 整合 rocketmq 发送事务消息](https://blog.csdn.net/weixin_42494845/article/details/109362030)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值