MQ消息太快导致的异步数据查询问题
程序员文章站
2022-03-07 13:28:12
...
先说问题:系统用到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,自己想把
上一篇: 5个你已经可以尝试的css新特性
下一篇: HttpClient简介与实现
推荐阅读
-
数据库查询中遭遇特殊字符导致问题的解决方法
-
MQ消息太快导致的异步数据查询问题
-
sql数据库查询结果字段包含换行符导致复制到Excel发生错位问题的解决
-
小程序云开发for循环中查询数据库异步执行的问题(ajax、axios都适用)
-
因数据库兼容级别低导致列转行查询出错问题的处理
-
因数据库兼容级别低导致列转行查询出错问题的处理
-
一个iframe实现长轮询,通过PHP查询数据库并用JS更新页面内容的程序,问题是并不是每一条MYSQL的INSERT消息都能显示到页面,求帮忙分析下哪里有问题
-
数据库查询中遭遇特殊字符导致问题的解决方法
-
一个iframe实现长轮询,通过PHP查询数据库并用JS更新页面内容的程序,问题是并不是每一条MYSQL的INSERT消息都能显示到页面,求帮忙分析下哪里有问题
-
sql数据库查询结果字段包含换行符导致复制到Excel发生错位问题的解决