4

我有一个 java 类,它使用来自队列的消息,将 HTTP 调用发送到一些 url。我在 google 和 stackoverflow 上进行了一些搜索(如果我错过了任何提及该问题的消息来源,我真的很抱歉),但找不到任何有关 setRollbackOnly 调用的详细信息。

我的问题是......如果我回滚,从队列中消耗的消息将阻塞队列的其余部分,并且将循环直到它被成功处理或者它将在当前队列的末尾重新排队?

我用于从队列中消费和发送 HTTP 调用的代码如下,整个应用程序在 Glassfish 服务器上运行:

公共类 RequestSenderBean 实现 MessageListener
{
  @资源
  私有 MessageDrivenContext mdbContext;

  公共 RequestSenderBean(){}

  public void onMessage(最终消息消息)
  {
    尝试
    {
      如果(对象消息的消息实例)
      {

          字符串 responseOfCall=sendHttpPost(URL, PARAMS_FROM_MESSAGE);

          如果(responseOfCall.startsWith(“成功”))
          {
            //一切正常,做一些事情
          }
          否则如果(responseOfCall.startsWith(“失败”))
          {
            //失败,做一些其他的事情
          }

    }
    捕获(最终异常 e)
    {
      e.printStackTrace();
      mdbContext.setRollbackOnly();
    }
  }
}
4

1 回答 1

5

这是基本的 JMS/消息传递知识。

队列实现“负载平衡”场景,即消息到达队列并被出队以由一个消费者处理。增加消费者的数量会增加该队列处理的潜在吞吐量。队列中的每条消息将由一个且只有一个消费者处理。

主题提供发布-订阅语义:一个主题的所有消费者都会收到推送到该主题的消息。

考虑到这一点,一旦消息被出列并(以事务方式)传递给消费者,如果它是异步的(如 MDB 的情况),则绝不会阻塞队列的其余部分。

正如Java EE 教程所述

消息消费

消息产品本质上是异步的:消息的生产和消费之间没有基本的时间依赖性。但是,JMS 规范在更精确的意义上使用这个术语。可以通过以下两种方式之一使用消息:

同步:订阅者或接收者通过调用接收方法从目的地显式获取消息。接收方法可以阻塞直到消息到达,或者如果消息在指定的时间限制内没有到达,则可以超时。

异步:客户端可以向消费者注册消息侦听器。消息侦听器类似于事件侦听器。每当消息到达目的地时,JMS 提供程序通过调用侦听器的 onMessage 方法来传递消息,该方法作用于消息的内容。

因为您使用MessageListener定义为异步的 a ,所以您不会阻塞队列或其后续处理。

本教程还包括以下内容:

使用会话 Bean 生成和同步接收消息

产生消息或同步接收消息的应用程序可以使用会话 bean 来执行这些操作。将 JMS API 与会话 Bean 一起使用的应用程序中的示例使用无状态会话 bean 将消息发布到主题。

因为阻塞同步接收占用了服务器资源,所以在企业 bean 中使用这样的接收调用不是一个好的编程实践。相反,使用定时同步接收,或使用消息驱动 bean 异步接收消息。有关阻塞和定时同步接收的详细信息,请参阅为同步接收示例编写客户端。

至于消息失败,这取决于你的队列是如何配置的。您可以设置错误队列(在 Glassfish 或 Weblogic 等容器的情况下),将失败的消息推送到以供以后检查。在您的情况下,您使用setRollbackOnly 的是这样处理的

7.1.2 编码消息驱动的 Bean:MessageBean.java

消息驱动的 bean 类 MessageBean.java 实现方法 setMessageDrivenContext、ejbCreate、onMessage 和 ejbRemove。onMessage 方法与 TextListener.java 的方法几乎相同,它将传入的消息转换为 TextMessage 并显示文本。唯一显着的区别是它在发生异常时调用 MessageDrivenContext.setRollbackOnly 方法。此方法回滚事务,以便重新传递消息。

我建议您阅读 Java EE 教程以及企业集成模式一书,其中详细介绍了与产品/技术无关的消息传递概念。

于 2013-09-16T08:23:57.150 回答