@Transactional事务内发送消息,消费端查不到数据报错。

问题:线上环境偶尔出现查不到数据,但人工查找的时候,数据是存在的。

原因:这一段代码里,插入了数据,事务未提交,发送了消息,另一边消费消息,去查询数据,查不到。

// 插入一条数据,发送了消息
@Transactional(rollbackFor = Exception.class)
public void addOneOrder() {
	// 插入数据
	insertOne();
	// 发送消息
	sendMQ();
}

//
// 另一边消费
@RabbitListener()
public void newConsumer(Message message) throws IOException {
	// 查询数据
	selectOne(); // 有概率查不到,所以导致线上偶尔报错。
}

解决方法:

  1. 最简单粗暴,消费地方,睡个几秒
  2. 事务提交后,才发送消息

第一种

// 另一边消费
@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);
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值