在我们的应用程序中,我们有以下快乐路径流程:
Node-Specific_queue 消息与 UUID-CorrelationId 相关
现在可以观察到,当在步骤 #2 和 #3 BE 尝试从
jmstTemplate.send
方法内部调用 JmsListener
到网关时,网关不会收到消息,直到控制权从 BE 侦听器方法中出来。我们不使用任何类型的交易。
我试图理解为什么它不起作用,到目前为止有效的是
jmsTemplate.send
是否在 JmsListener
方法内的单独线程中执行。为什么用线程执行这段代码JMSListener
不起作用?是否有任何外部配置可以在不更改任何代码的情况下提供帮助?
在同一线程上时,JMS 代理将不会执行 send(),直到来自侦听器的消息 receive() 得到确认。这就是为什么在侦听器方法存在之前您看不到消息的原因。此上下文是线程本地的,因此如果您启动一个新线程,您将不会看到此行为。
我怀疑您使用相同的 JMS 连接工厂进行接收和侦听。如果您对这些操作使用不同的 JMS 连接工厂,您可能看不到此行为。
根据你的问题...
这是一个很长的问答。 AbstractMessageListenerContainer 的 javadoc 可能会有所帮助。
最初,当用户使用 DefaultMessageListenerContainer 时,默认行为是立即 ACK 传入消息。用户必须知道,如果发生异常,传入消息已被确认,并且可能会发生消息丢失。您必须设置某种形式的事务,以便延迟发送传入消息的 ACK,直到处理完成。
为此目的使用 JmsTransactionManager 很常见。请注意,
JmsTransactionManager
只能管理单个 JMS 连接工厂。这就是为什么使用不同的连接工厂可以解决与 JmsTransactionManager
的事务。
使用现代模板,这是为您设置的。您实际上正在使用事务,并且当侦听器存在时,入站消息将被确认(除非您使用其他事务方法扩展事务上下文)。