1.概念:
参考你兄弟借钱你管你老婆要的现实。。:
事务消息状态
- 提交状态:允许进入队列,此消息与非事务消息无区别(爽快借出!)
- 回滚状态:不允许进入队列,此消息等同于未发送过(直接回复不借!)
- 中间状态:完成了half消息的发送,未对MQ进行二次状态确认(拖着不回复)
- 注意:事务消息仅与生产者有关,与消费者无关
2.代码:
注意:别关生产者!!!
生产者(事务正常过程和补偿过程逻辑自写):
public class Producer {
public static void main(String[] args) throws Exception {
//1. 事务消息生产者
TransactionMQProducer producer = new TransactionMQProducer("group1");
producer.setNamesrvAddr("localhost:9876");
//设置事务监听
producer.setTransactionListener(new TransactionListener() {
//正常事务过程
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
System.out.println("执行正常事务过程");
//把消息保存到mysql数据库
//if(sql insert){
//return LocalTransactionState.COMMIT_MESSAGE;
//}else {
//return LocalTransactionState.ROLLBACK_MESSAGE;
//}
//return LocalTransactionState.COMMIT_MESSAGE;
//结果数据库崩了!那么消费者收不到消息
//return LocalTransactionState.ROLLBACK_MESSAGE;
return LocalTransactionState.UNKNOW;
}
//事务补偿过程
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
System.out.println("执行事务补偿过程");
//if(sql select){
//
//}else {
//
//}
//UNKNOW 保存 这个消息事务补偿未知,请运维人员手工介入
//运维 看到
return LocalTransactionState.UNKNOW;
}
});
producer.start();
String msg="hello world yuandongli transaction1";
Message message = new Message("topic13", "tag1", msg.getBytes());
//发送事务消息
TransactionSendResult sendResult = producer.sendMessageInTransaction(message, null);
System.out.println(sendResult);
//别关生产者
}
}
消费者:
public class Consumer {
public static void main(String[] args) throws Exception {
//1. 谁来收?
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
//2. 从哪里收消息?
consumer.setNamesrvAddr("localhost:9876");
//3. 监听哪个消息队列
consumer.subscribe("topic13","*");
//4. 处理业务流程 注册监听器
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
//写我们的业务逻辑
for (MessageExt msg : msgs) {
System.out.println(msg);
byte[] body = msg.getBody();
System.out.println(new String(body));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
System.out.println("消费者起起来了");
//千万别关消费者
}
}
更清晰的事务消息状态代码:
提交状态
//事务消息使用的生产者是TransactionMQProducer
TransactionMQProducer producer = new TransactionMQProducer("group1");
producer.setNamesrvAddr("localhost:9876");
//添加本地事务对应的监听
producer.setTransactionListener(new TransactionListener() {
//正常事务过程
public LocalTransactionState executeLocalTransaction(Message message, Object o) {
return LocalTransactionState.COMMIT_MESSAGE;
}
//事务补偿过程
public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
return null;
}
});
producer.start();
Message msg = new Message("topic8",("事务消息:hello rocketmq ").getBytes("UTF-8"));
SendResult result = producer.sendMessageInTransaction(msg,null);
System.out.println("返回结果:"+result);
producer.shutdown();
回滚状态
producer.setTransactionListener(new TransactionListener() {
//正常事务
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
return LocalTransactionState.ROLLBACK_MESSAGE;
}
//事务补偿
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
return null;
}
});
中间状态
public static void main(String[] args) throws Exception {
TransactionMQProducer producer=new TransactionMQProducer("group1");
producer.setNamesrvAddr("localhost:9876");
producer.setTransactionListener(new TransactionListener() {
//正常事务
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
return LocalTransactionState.UNKNOW;
}
//事务补偿 正常执行UNKNOW才会触发
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
System.out.println("事务补偿");
return LocalTransactionState.COMMIT_MESSAGE;
}
});
producer.start();
Message msg = new Message("topic13", "hello rocketmq".getBytes("UTF-8"));
SendResult result = producer.sendMessageInTransaction(msg, null);
System.out.println("返回结果:" + result);
//事务补偿生产者一定要一直启动着
//producer.shutdown();
}