先说问题:系统用到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,自己想把
相关推荐
MQ消息测试工具 可直接向MQ写消息 用于MQ消息接收程序的测试
NULL 博文链接:https://bijian1013.iteye.com/blog/2317339
描述MQ消息持久化,在队列管理器发生异常时,传送到队列中的信息怎样通过日志将信息恢复到队列中。
mq消息头详细介绍,对我是很有帮助的,分享给大家
一个C#实现IBM WebSphere MQ 消息收发的实例,包含 发送接收等. 使用的时候只需要修改 appconfig 文件的内容即可. 如有问题.请留言
一个C#实现IBM WebSphere MQ 消息收发的实例,自己平时写的,如遇困难,请留言
NULL 博文链接:https://bijian1013.iteye.com/blog/2317341
3)进入/opt/mqm/samp/bin,使用样本程序amqsputc(用来将消息发送到服务端队列)和amqsgetc(用来从服务端队列中读取消息)来测试客户端与服务端的MQ连接是否畅通,具体步骤如下: 输入命令: ./amqsputc ...
Java向MQ发送消息三种方式
MQ基本概念1、对列管理器 队列管理器是MQ系统中最上层的一个概念,由它为我们提供基于队列的消息服务。2、消息 在MQ中,我们把应用程序交由MQ传输的数据定义为消息,我们可以定义消息的内容并对消息进行广义的理解
基于Go实现的分布式MQ消息队列
IBM-MQ消息分组与分段实验,有PDF技术文档,以及C写的DEMO。
MQ发送消息源代码
JAVA IBM MQ 接收消息、发送消息例子
IBM MQ将消息发送至远程队列,文档详细,有截图,有命令
JAVA向MQ发送消息, JAVA向MQ发送消息, JAVA向MQ发送消息,
模仿 rabbitmq 写的一个消息推送机制,
WebSphere MQ一小时快速入门 1、WebSphere MQ简介 2、WebSphere MQ主要对象 3、WebSphere MQ体系结构 4、MQ的本地安装 5、MQ的服务器到服务器安装
IBMMQ消息队列源码
作为中间件,消息队列是...所以消息队列可以解决应用解耦、异步消息、流量削锋等问题,是实现高性能、高可用、可伸缩和最终一致性架构中不可以或缺的一环。文档为市场上流行的消息队列以列表对比形式进行分析,比较全面