问题:线上环境偶尔出现查不到数据,但人工查找的时候,数据是存在的。
原因:这一段代码里,插入了数据,事务未提交,发送了消息,另一边消费消息,去查询数据,查不到。
// 插入一条数据,发送了消息
@Transactional(rollbackFor = Exception.class)
public void addOneOrder() {
// 插入数据
insertOne();
// 发送消息
sendMQ();
}
//
// 另一边消费
@RabbitListener()
public void newConsumer(Message message) throws IOException {
// 查询数据
selectOne(); // 有概率查不到,所以导致线上偶尔报错。
}
解决方法:
- 最简单粗暴,消费地方,睡个几秒
- 事务提交后,才发送消息
第一种
// 另一边消费
@RabbitListener()
public void neworderConsumer(Message message) throws IOException {
sleep(3000); // 等待几秒
// 查询数据
selectOne(); // 有概率查不到,所以导致线上偶尔报错。
}
第二种 参考的这篇博客@Transactional事务提交后执行异步任务
TransactionSynchronization接口的afterCommit()方法,最终在事务commit提交后执行发送消息
// 插入一条数据,发送了消息
@Transactional(rollbackFor = Exception.class)
public RestMessage addOneOrder() {
// 插入数据
insertOne();
// 发送消息
// sendMQ();
sendRabbitMq();
}
// 事务提交后,发送消息
public void sendRabbitMq(String msg) {
// 注册事务同步处理
if (TransactionSynchronizationManager.isActualTransactionActive()) {
//存在事物
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
// 发送消息
sendMQ(msg);
}
});
} else {
// 发送消息
sendMQ(msg);
}
}