rocketmq 事务消息
********************************************
rocketmq支持事务消息,实现方式:
rocketmq发送prepared消息;
发送成功后,执行本地事务;
prepared消息根据本地事务的执行状态提交或者回滚,若长时间没有收到本地事务的执行状态,则调用回调函数检查本地事务的执行状态
********************************************
相关接口
public interface TransactionListener {
LocalTransactionState executeLocalTransaction(Message var1, Object var2);
//执行本地事务
LocalTransactionState checkLocalTransaction(MessageExt var1);
//回查本地事务的执行状态
}
*****************************************
本地事务的执行状态
public enum LocalTransactionState {
COMMIT_MESSAGE, //提交
ROLLBACK_MESSAGE, //回滚
UNKNOW; //未知
private LocalTransactionState() {
}
}
************************************************
使用示例
***********************************
producer 端
@Service
public class TransactionProducerService {
@Value("${rocketmq.namesrv}")
private String namesrv;
@Autowired
private LocalExecutor localExecutor;
private TransactionMQProducer producer;
@PostConstruct
public void initTransactionMQProducer(){
producer=new TransactionMQProducer("transactionProducer");
producer.setNamesrvAddr(namesrv);
try{
producer.start();
}catch (Exception e){
e.printStackTrace();
}
}
public void sendInTransaction() {
producer.setTransactionListener(localExecutor);
try {
for (int i = 0; i < 10; i++) {
Message message = new Message("topic-3", "transaction", ("瓜田李下 事务消息"+Integer.toString(i)).getBytes());
TransactionSendResult result=producer.sendMessageInTransaction(message,i);
System.out.println(result);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@PreDestroy
public void destroy(){
if(producer!=null) {
producer.shutdown();
}
}
}
@Component
class LocalExecutor implements TransactionListener{
private ConcurrentHashMap<String, LocalTransactionState> map=new ConcurrentHashMap<>();
@Override
public LocalTransactionState executeLocalTransaction(Message message, Object o) {
map.put(message.getTransactionId(),LocalTransactionState.UNKNOW);
Integer i=Integer.valueOf(o.toString());
if (i.equals(2)){
System.out.println("本地函数出错,回滚事务消息");
map.put(message.getTransactionId(),LocalTransactionState.ROLLBACK_MESSAGE);
}else {
map.put(message.getTransactionId(),LocalTransactionState.COMMIT_MESSAGE);
}
return map.get(message.getTransactionId());
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
return map.get(messageExt.getMsgId());
}
}
****************************************
consumer 端
@Service
public class ConsumerService {
@Value("${rocketmq.consumerGroup}")
private String consumerGroup;
@Value("${rocketmq.namesrv}")
private String namesrv;
@PostConstruct
public void consumeTransaction(){
DefaultMQPushConsumer consumer=new DefaultMQPushConsumer("transactionConsumer");
consumer.setInstanceName("consumerGroup3");
consumer.setNamesrvAddr(namesrv);
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
try{
Thread.sleep(2000);
consumer.subscribe("topic-3","transaction");
consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> {
try{
for(MessageExt messageExt:list){
String body=new String(messageExt.getBody());
System.out.println(body);
System.out.println("消费成功");
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}catch (Exception e){
System.out.println("消费失败");
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
});
}catch (Exception e){
e.printStackTrace();
}
try{
consumer.start();
}catch (Exception e){
e.printStackTrace();
}
}
}
********************************************
控制台输出
发送端输出
消费端输出