package com.gupao;
import com.gupao.listener.TransactionListenerLocal;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import java.io.UnsupportedEncodingException;
import java.rmi.Remote;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TransactionProducer {
public static void main(String[] args) throws MQClientException, UnsupportedEncodingException, InterruptedException {
TransactionMQProducer producer=new TransactionMQProducer("tx_producer");
producer.setNamesrvAddr("192.168.1.111:9876");
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
producer.setExecutorService(executorService);
producer.setTransactionListener(new TransactionListenerLocal());//本地事务的监听
producer.start();
for (int i = 0; i < 20; i++) {
String orderId= UUID.randomUUID().toString();
String body="{'opertion':'doOrder','orderId':'"+orderId+"'}";
// 主题 标签 keys message内容
Message message=new Message("order_tx_topic","tagA",orderId,body.getBytes(RemotingHelper.DEFAULT_CHARSET));
producer.sendMessageInTransaction(message,orderId+"&"+i);
Thread.sleep(1000); //每隔一秒 发送一条信息
}
}
}
二: 本地事务处理
package com.gupao.listener;
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;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class TransactionListenerLocal implements TransactionListener {
Map<String,Object> results=new HashMap<>();
//执行本地事务
@Override
public LocalTransactionState executeLocalTransaction(Message message, Object o) {
System.out.println("开始执行本地事务: "+o.toString());
String orderId=o.toString();
boolean result=Math.abs(Objects.hash(orderId))%2==0;//模拟 业务操作成功 或者失败
results.put(orderId,result);
//反馈 给生产者 COMMIT_MESSAGE (代表处理业务成功) UNKNOW(处理业务失败)
return result?LocalTransactionState.COMMIT_MESSAGE:LocalTransactionState.UNKNOW;
}
//提供给事务执行状态检查 的 回调方法 给broker用的 (异步回调)
@Override// 重新检查 UNKNOW(处理业务失败)的数据 如果是真的业务失败 则进行事务回滚
public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
String orderId = messageExt.getKeys();
System.out.println("执行事务回调检查:orderId="+orderId);
boolean result = (boolean) results.get(orderId);
System.out.println("事务的处理结果是:"+result);//只有成功 或者失败(回滚)
return result?LocalTransactionState.COMMIT_MESSAGE:LocalTransactionState.ROLLBACK_MESSAGE;
}
}
三: 客户端接收
package com.gupao;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import java.util.List;
public class TransactionConsumer {
public static void main(String[] args) throws MQClientException {
DefaultMQPushConsumer defaultMQPushConsumer = new DefaultMQPushConsumer("tx_consumer");
defaultMQPushConsumer.setNamesrvAddr("192.168.1.111:9876");
defaultMQPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
// subExpression 支持sql表达式 or and
defaultMQPushConsumer.subscribe("order_tx_topic","*");
defaultMQPushConsumer.registerMessageListener(new MessageListenerConcurrently() { //并发模式监听
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
list.stream().forEach(message->{
System.out.println("开始业务处理逻辑: 消息体:"+new String(message.getBody())+"->keys:"+message.getKeys());
});
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;//签收消息
}
});
defaultMQPushConsumer.start();
}
}