JMS:可以在一个线程上通过MessageConsumer.rereceive()进行读取,然后从另一个线程调用Sess



JMS会话的规范警告说,只有当有MessageListener实例注册到会话时,会话对象/实例才能在创建它们的线程上使用。然而,当使用MessageConsumer对象(仅)时,它并没有说明线程不安全,或者更准确地说,"线程绑定"。

http://docs.oracle.com/javaee/1.3/api/javax/jms/Session.html

(所谓"线程绑定",我的意思是该对象只能在特定线程上使用,而不仅仅是在没有同步或其他协调的情况下在多个线程上使用它是不安全的)

这个问题的答案还表明会话是线程绑定的:JMS连接、会话和生产者/消费者之间的关系

然而,作者可能做出了一些假设,也可能没有做出一些假设,问题也更多地是关于消息,而不是关于

有人知道你是否可以在一个线程上读取会话中的消息,然后让另一个线程处理该消息,并在另一个螺纹上对消息(与会话)进行提交/回滚吗?只有commit(或rollback)会从处理线程中对会话进行调用,而不会对Connection/Session/MessageConsumer/Message链进行其他调用。此外,只有在提交/回滚发生之后,会话才会用于再次读取。

以下S/O问题似乎密切相关,但并不能令人满意地解决我的建议:

如何连续读取线程中的JMS消息,并根据另一个线程中的JMSMessageID确认它们?

在单线程上下文中使用JMS会话对象的原因

虽然我想在多个线程上使用会话,但永远不会有重叠的消息请求/事务。

我试图避免对现有代码进行进一步的重构,所以我考虑做一些奇怪的事情,而不是在每个工作线程上都有一个Session。

      • 编辑(七月二十六日)-

这个问题,使用来自不同线程的JMS会话,似乎表明可以在不同线程上对会话执行同步操作,但我不确定引用了规范的哪个版本。

也许您已经在规范中找到了一种方法。

引用Se博士的话ssionhttp://docs.oracle.com/javaee/1.3/api/javax/jms/Session.html

Session对象是一个单线程上下文,用于生成和使用消息。尽管它可以在Java虚拟机(JVM)之外分配提供程序资源,但它被认为是轻量级JMS对象。

所以它是单线程的;而且创建一个并不昂贵。

你必须注意

close方法是唯一可以调用的会话方法,而其他一些会话方法正在另一个线程中执行

例如,您必须确保readcommit不重叠。

从技术角度来看,我会重构它;代码将更易于阅读/维护。资源处理(打开/关闭)只能在一个线程(一个方法)中进行。这也将简化异常处理。

[从法律的角度来看:你承认你在做一些"奇怪"的事情——违背了建议。我不会提供这样的软件。]

相关内容

最新更新