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

我是JMS的新手。 因此,对于这里的专家而言,这可能是一个非常高的问题。 但是,我很难找到一个关于JMS如何布局工作的非常重要的概念。

来自JMS Session的Javadoc (大胆强调我的)

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

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

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

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

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

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

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