发送事务消息的实现
- 要使用TransactionMQProducer作为消息的生产者,
- 生产者需要注册TransactionListener
- executeLocalTransaction 是执行本地事务的方法
- checkLocalTransaction 是回查事务状态的
- 发送消息的时候使用sendMessageInTransaction()方法
事务消息的流程
- 生产者发送一条事务消息成功之后并不能被消费者消费(这样的一条消息被称为半消息)
- 生产者在executeLocalTransaction方法中执行完本地事务之后,
- 返回LocalTransactionState.COMMIT_MESSAGE; 事务提交,消息会被消费者消费
- 返回LocalTransactionState.ROLLBACK_MESSAGE; 事务回滚,消息会被回滚,消费者无法消费消息
- 返回LocalTransactionState.UNKNOW; 未知状态,消息队列会稍后通过回调checkLocalTransaction方法再次查看事务状态
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
/**
* 发送事务消息
*/
public class Producer {
public static void main(String[] args) throws MQClientException {
TransactionMQProducer producer = new TransactionMQProducer("transactionGroup");
producer.setNamesrvAddr("192.168.197.126:9876;192.168.197.123:9876");
//设置TransactionListener
producer.setTransactionListener(new TransactionListener() {
//处理本地事务
@Override
public LocalTransactionState executeLocalTransaction(Message message, Object o) {
System.out.println("executeLocalTransaction-->tag="+message.getTags());
if(StringUtils.equals("TAGA",message.getTags())){
return LocalTransactionState.COMMIT_MESSAGE;
}else if(StringUtils.equals("TAGB",message.getTags())){
return LocalTransactionState.ROLLBACK_MESSAGE;
}else{
return LocalTransactionState.UNKNOW;
}
}
//检查事务结果
@Override
public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
System.out.println("checkLocalTransaction-->tag="+messageExt.getTags());
if(StringUtils.equals("TAGC",messageExt.getTags())){
return LocalTransactionState.COMMIT_MESSAGE;
}else{
return LocalTransactionState.ROLLBACK_MESSAGE;
}
}
});
producer.start();
String[] tags = {"TAGA","TAGB","TAGC"};
for (int i = 0; i < 3; i++) {
Message message = new Message("transactionTopic",tags[i],("transactionMessgae"+i).getBytes());
//发送事务消息
producer.sendMessageInTransaction(message,null);
}
}
}