【问题标题】:Reason for a JMS Session object to be used in a single threaded context在单线程上下文中使用 JMS 会话对象的原因
【发布时间】:2013-06-23 16:54:51
【问题描述】:

我是 JMS 的新手。因此,对于 SO 中的专家来说,这可能是一个非常菜鸟的问题。 但是,我很难理解 JMS 是如何工作的一个非常重要的概念。

来自Javadoc of the JMS Session(我的粗体强调)

Session 对象是一个单线程上下文,用于生成和 消费消息。虽然它可能会分配提供者资源 在 Java 虚拟机 (JVM) 之外,它被认为是轻量级的 JMS 对象。

我认为 JMS 的主要优点是消息的异步传递异步 一词自动适用于多个线程同时生产和消费消息的概念。所以我对所有重要的Session 对象的单线程上下文的概念感到困惑。我在这里错过了什么?

【问题讨论】:

    标签: java multithreading concurrency jms


    【解决方案1】:

    这与 JTA 是单线程的原因相同。关于如何/何时安排线程运行没有任何硬性保证。此外,如果没有同步,则无法保证线程何时完成其工作。鉴于这些限制,很难在保持并行处理优势的同时创建事务保证。

    例如,如果我生成一个事务,然后生成一个在该事务上发送消息的线程,但在主线程中任意提交事务,事务管理器应该怎么做(忽略commit()?失败@987654322 @?)。如果我还有其他尚未完成的事务性工作(数据库提交),但我的消息发送线程已完成并调用了commit(),该怎么办?如果在 TransactionManager 试图确定所有事务参与者的2-Phase-Commit 状态时线程启动并开始更多工作怎么办?

    事务 API 都基于明确定义的工作单元。当工作单元在单个线程中运行时,这些 API 非常清晰。否则事情会变得复杂,并被 Java EE 规范未解决的实现所涵盖。这些事务管理器允许嵌套事务和/或跨越多个线程的事务。这些实现使用非常精心设计的同步,用例有限,而且很可能最终只是将工作序列化。

    对于大多数用户来说,JMS 的主要好处类似于任何基于消息的参与者系统。许多离散的步骤可以拉取队列中的消息,处理它们,通过将结果放在另一个队列中前进到下一步。如果任何步骤成为瓶颈,您可以添加更多处理代理(MDB、spring bean 等)。每个代理在单个线程上进行处理,您可以通过创建更多代理扩展到多个内核。

    【讨论】:

    • 同一条消息的生产者和消费者共享同一个会话还是可以不同?
    • 会话限定了与代理的事务。您可以在同一会话中生成和使用消息。事实上,如果你想从Queue A消费并生产到Queue B,你必须这样做
    • 我还有一个疑问。当您在回答中提到 主线程 时,您实际上指的是哪个线程?
    【解决方案2】:

    Session 类处理事务。因此,虽然通常只有一个Connection,但您可以让多个线程拥有自己的会话上下文,每个线程都有自己的事务上下文。

    【讨论】:

      猜你喜欢
      • 2013-12-31
      • 2015-07-23
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 2014-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多