实战:RocketMQ高级功能代码实现

1,事务消息代码实现

      之前我们已经在讨论订单业务消息丢失问题中引出了事务消息,本内容我们就实际用代码来实现一下事务消息吧。

    首先我们用原生代码来实现一下事务消息,下面是事务消息生产者TransactionProducer类的代码,具体代码解释已经用注释标明。

package com.huc.rocketmq.transaction;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;

import java.io.UnsupportedEncodingException;
import java.util.concurrent.*;

/**
 * @author liumeng
 */
public class TransactionProducer {
public static void main(String[] args)
 throws MQClientException, UnsupportedEncodingException {
        // 这里是一个自定义的接收RocketMQ回调的监听接口
        TransactionListener transactionListener = new TransactionListenerImpl();
        // 创建支持事务消息的Producer,并指定生产者组
        TransactionMQProducer producer =
                new TransactionMQProducer("testTransactionGroup");
        // 指定一个线程池,用于处理RocketMQ回调请求的
        ExecutorService executorService = new ThreadPoolExecutor(
                2,
                5,
                100,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(2000),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable r) {
                        Thread thread = new Thread(r);
                        thread.setName("testThread");
                        return thread;
                    }
                }
        );
        // 给事务消息生产者设置线程池
        producer.setExecutorService(executorService);
        // 给事务消息生产者设置回调接口
        producer.setTransactionListener(transactionListener);
        // 启动生产者
        producer.start();
        // 构造一条订单支付成功的消息
        Message message = new Message(
                "PayOrderSuccessTopic",
                "testTag",
                "testKey",
                "订单支付消息".getBytes(RemotingHelper.DEFAULT_CHARSET)
        );

        // 将消息作为half消息发送出去
        try {
            TransactionSendResult result = producer.sendMessageInTransaction(message, null);
        } catch (Exception e) {
           // half消息发送失败
            // 订单系统执行回滚逻辑,比如退款、关闭订单
        }
    }
}

     针对于half消息发送失败的情况,是有可能一直接收不到消息发送失败的异常的,所以我们可以在发送half消息的时候,同时保存一份half消息到内存中,或者写入磁盘里,后台开启线程去检查half消息,如果超过10分钟都没有接到响应,就自动执行回滚逻辑。

      那么如果half消息成功了,如何执行本地事务逻辑呢?这就要说到代码中自定义的回调监听接口TransactionListenerImpl类了,代码如下:

package com.huc.rocketmq.transaction;

import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;

public class TransactionListenerImpl implements TransactionListener {
    /**
     * 如果half消息发送成功了,就会回调这个方法,执行本地事务
     * @param message
     * @param o
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的尤克里里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值