【问题标题】:JMS: Can we get multiple messages from queue in OnMessage() withtout commit or rollbackJMS:我们可以在 OnMessage() 中从队列中获取多条消息而无需提交或回滚吗
【发布时间】:2014-08-18 11:56:21
【问题描述】:

我正在使用从远程服务器接收 JMS 消息的 JMS 客户端。 我正在客户端的 onMessage() 方法中监听 JMS 消息。

我面临的问题是,即使我定期在客户端使用消息,消息也会在服务器端累积。

根据我在客户端所做的处理,我会发送一个 rollback() 或 commit()。

我有一个查询,当我正在处理 JMS 消息并且我没有向队列发送 commit() 时,我能否从服务器获取另一条消息。

请注意,对于处理,我正在等待处理同步块中收到的消息。 当我仍在处理并且尚未向队列发送提交时,我会收到一条新消息吗?

【问题讨论】:

    标签: java jms


    【解决方案1】:

    MessageListener#onMessage() 作为会话线程的一部分执行, 所以在从 onMessage() 返回之前,您不会收到下一条消息。

    一般来说,如果预计会花费更多时间,则不应在 onMessage() 中处理消息。将消息排入单独的数据结构并让其他线程处理它。

    你不必在每条消息之后都调用commit(),你可以继续接收消息。

    没有。未调用提交/回滚接收的消息取决于客户端缓冲区大小 - 通常可在队列/全局配置。

    请注意,对于处理,我正在等待 处理在同步块中接收到的消息。我会得到 在我仍在处理且尚未发送提交时收到一条新消息 去排队?

    如果你在 onMessage() 中处理,你将不会收到新消息,所以不需要在 onMessage() 中设置同步块。

    【讨论】:

    • 请注意,docs.oracle.com/javaee/7/api/javax/jms/… 的 JMS API 文档明确指出 MessageListener#onMessage() 是异步的,只有 MessageConsumer#receive() 是同步的。在我的测试中,这两种方法似乎都在阻塞,直到有新消息到达(使用 Wildfly-9 和 HornetQ),但只有 receive() 工作可靠,所以最好坚持官方记录的行为。
    【解决方案2】:

    如果您创建了一个会话并创建了一个消息使用者并设置了您的消息侦听器实例,那么根据 java 文档,只有一个消息侦听器实例将在任何给定时间点收到消息,因为会话本身会处理如果为同一会话注册,则跨多个侦听器进行序列化。

    “用于创建消息消费者的会话将所有注册到该会话的消息侦听器的执行序列化。任何时候,只有一个会话的消息侦听器在运行。”

    JMS MessageListeners

    “每个会话必须确保将消息串行传递给侦听器。这意味着分配给同一会话的一个或多个消费者的侦听器可以假设 onMessage 方法不会与下一条消息一起调用,直到session 已完成最后一次通话。"

    JMS MessageListener

    简而言之,您的查询:-

    我有一个查询,当我正在处理 JMS 消息并且我没有向队列发送 commit() 时,我能否从服务器获取另一条消息。

    如果您创建了一个会话,即使您创建了多个侦听器实例,答案是否定的。

    但是,如果您创建多个会话并创建消息侦听器的多个实例并注册它们,那么它们可能会在每个会话同时接收多条消息

    另外,对于您正在消费消息但消息仍在累积的问题,您需要创建多个并发会话,这将提高您的消息处理速度,从而减少服务器中的消息积累

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-25
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      相关资源
      最近更新 更多