实际项目中,我们会经常用到MQ,比如RabbitMQ。
通常会遇到一个问题:当在一个开启事务的方法里面发送MQ,经常会遇到事务还没提交,但是消息却已经消费完了。而如果消费者需要用到提交后的数据,则会报错或出现问题。
解决方案
事务提交后再发送MQ,代码如下
AmqpTemplateHelper.java
@Component
public class AmqpTemplateHelper {
@Autowired
private AmqpTemplate amqpTemplate;
/**
* 事务提交后发送MQ
* @param queue
* @param message
* @param <T>
*/
public <T> void send(String queue, T message) {
// 是否开启事务判断
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
amqpTemplate.convertAndSend(queue, message);
}
});
} else {
amqpTemplate.convertAndSend(queue, message);
}
}
}
使用示例:
@Autowired
private AmqpTemplateHelper amqpTemplateHelper;
@Transactional(rollbackFor = Throwable.class)
public void save() {
Person person = new Person();
String id = "123";
person.setId(id);
baseMapper.insert(person);
amqpTemplateHelper.send("QUEUE_NAME", id);
}