MQ消息太快导致的异步数据查询问题

先说问题:系统用到mq发送消息,实际运行时发现mq的接收端程序在接收到消息之后,去查询业务数据的状态时发现仍然是老的状态,导致程序处理数据异常;手动去数据查询时发现是新的状态。
经分析,应该是mqserver和应用在同一个机器,mq消息太快,导致接收端程序查询时,发送端程序的数据库事务还没有提交完成,所以查询到的结果是老的数据。
如果你想思考一下,那就先暂停
-----------------------以下是解决方案------------------------------------------------------
解决方案:最初的方案是接收端延迟执行,拿到消息后 sleep1s,然后再执行,但是这是个很不好的处理,因为1s这个时间对发送端程序来说是不确定的,有可能1s是不够用的,那就用2s,3s?真不是一个好方案,但是勉强能用。
方案改进:后来又再次遇到了同样的问题,于是思考了一番,如下改进步骤:
改进1:既然与事务有关,那能不能把消息发送放在事务提交后?
实现:程序调用mq代理接口发送消息时并不真正的发送消息,而是把消息存储在ThreadLocal中,系统采用的是 springboot的事务管理:DataSourceTransactionManager,实现自定义MyDataSourceTransactionManager 继承 DataSourceTransactionManager,重写 doCommit 方法,在调用完父类的doCommit之后,查看 ThreadLocal中是否有消息,有的话就调用真正的mq发送接口发送消息;重写doCleanupAfterCompletion 方法,调用父类的doCleanupAfterCompletion 后,清理ThreadLocal中的消息。
问题:有的消息发送可能和事务无关,或者发送消息的线程中没有事务,这样就会导致消息没有真正发送
改进2:既然有没有事务的,那是不是可以在程序调用mq代理接口时查询当前线程是否有正在进行的事务,如果有,就存储消息到ThreadLocal,如果没有,就直接发送
实现:可通过 DataSourceTransactionManager.isExistingTransaction来实现
 
问题:在有事务的情况下,事务提交时发送消息,会不会影响到事务的提交?mq发送消息是网络调用,会不会影响程序的效率?
改进3,自己想把
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值