使用setRollbackOnly的JMS和MDB

时间:2013-09-16 08:07:20

标签: java glassfish jms message-driven-bean

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

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

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

public class RequestSenderBean implements MessageListener
{
  @Resource
  private MessageDrivenContext mdbContext;

  public RequestSenderBean(){}

  public void onMessage(final Message message)
  {
    try
    {
      if(message instanceof ObjectMessage)
      {

          String responseOfCall=sendHttpPost(URL, PARAMS_FROM_MESSAGE);

          if(responseOfCall.startsWith("Success"))
          {
            //Everything is OK, do some stuff
          }
          else if(responseOfCall.startsWith("Failure"))
          {
            //Failure, do some other stuff
          }

    }
    catch(final Exception e)
    {
      e.printStackTrace();
      mdbContext.setRollbackOnly();
    }
  }
}

1 个答案:

答案 0 :(得分:5)

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

队列实现“负载平衡”方案,其中消息命中队列并被一个消费者处理。增加消费者数量会增加该队列处理的潜在吞吐量。队列中的每条消息都将由一个且只有一个消费者处理。

主题提供发布 - 订阅语义:主题的所有使用者都将收到推送到主题的消息。

考虑到这一点,一旦消息被解除并交给消费者,它就不会阻塞队列的其余部分(如果它是异步的)(如MDB的情况)。

作为Java EE Tutorial states

  

消息消费

     

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

     

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

     

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

因为您使用的是MessageListener,根据定义异步,您不会阻止队列或其后续处理。

同样来自the tutorial的内容如下:

  

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

     

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

     

由于阻塞同步接收会占用服务器资源,因此在企业bean中使用此类接收调用并不是一种好的编程习惯。相反,使用定时同步接收,或使用消息驱动的bean异步接收消息。有关阻塞和定时同步接收的详细信息,请参阅为同步接收示例编写客户端。

至于消息失败,它取决于您的队列配置方式。您可以设置错误队列(在Glassfish或Weblogic等容器的情况下),将失败的消息推送到以后检查。在您的情况下,您使用的是setRollbackOnly which is handled thus

  

7.1.2编写消息驱动Bean:MessageBean.java

     

消息驱动的bean类MessageBean.java实现了   方法setMessageDrivenContext,ejbCreate,onMessage和ejbRemove。   onMessage方法,几乎​​与TextListener.java相同,   将传入消息强制转换为TextMessage并显示文本。该   唯一明显的区别就是它所谓的   发生异常时的MessageDrivenContext.setRollbackOnly方法。   此方法回滚事务以便消息   重新传送。

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