在RocketMQ中,事务消息(Transaction Message)是一种特殊类型的消息,用于保证消息的可靠性投递,即使在生产者和消息代理之间发生异常情况时也能确保消息不会丢失或重复投递。事务消息适用于需要在发送消息后进行本地事务处理的场景,只有在本地事务成功提交后,消息才会被正式发送到消息队列中。
官网事务消息处理流程
实现事务消息的步骤
1. 定义事务监听器接口
首先,需要定义一个实现 RocketMQ 的 TransactionListener
接口的事务监听器,用于处理本地事务的执行和消息的提交或回滚。
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
public class YourTransactionListener implements TransactionListener {
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
// 执行本地事务,根据本地事务执行的结果返回对应的状态
// 例如,假设这里是一个数据库操作,如果操作成功则返回 COMMIT_MESSAGE,否则返回 ROLLBACK_MESSAGE
// 根据实际情况编写具体的本地事务逻辑,确保本地事务和消息的一致性
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
// 检查本地事务的状态,根据本地事务的执行结果返回对应的状态
// 例如,如果本地事务执行成功,则返回 COMMIT_MESSAGE;如果本地事务未完成,则返回 UNKNOW,RocketMQ将稍后重新检查本地事务状态
}
}
2. 配置事务消息的生产者
在Spring Boot项目中配置RocketMQ的事务消息生产者。
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TransactionalProducer {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Autowired
private YourTransactionListener transactionListener;
public void sendTransactionalMessage(String topic, String message) {
// 第一个参数是消息主题,第二个参数是消息体,第三个参数是本地事务监听器,第四个参数是传递给本地事务的参数
rocketMQTemplate.sendMessageInTransaction(topic, message, null, transactionListener);
}
}
3. 消费事务消息
消费事务消息与普通消息消费类似,需要实现 RocketMQ 的 RocketMQListener
接口,并在 @RocketMQMessageListener
注解中指定消费者组和主题。
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
@Service
@RocketMQMessageListener(topic = "your-topic", consumerGroup = "your-consumer-group")
public class TransactionalConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("Transactional Consumer received: " + message);
// 处理事务消息的消费逻辑
}
}
注意事项
- 本地事务的一致性:确保在执行本地事务和消息发送之间保持一致性,避免出现消息丢失或重复消费的情况。
- 本地事务的执行时间:本地事务应该在较短的时间内执行完成,以避免 RocketMQ 超时重试机制引起的问题。
- 消息处理的幂等性:在消息消费端实现幂等性,防止由于消息重复投递或者重试机制导致的消息处理多次执行的问题。