首页 文章

使用setRollbackOnly的JMS和MDB

提问于
浏览
4

我有一个java类,它消耗来自队列的消息,向一些URL发送HTTP调用 . 我已经在google上进行了一些搜索,也在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 回答

  • 5

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

    队列实现“负载 balancer ”场景,其中消息命中队列并被解除以由一个消费者处理 . 增加消费者数量会增加该队列处理的潜在吞吐量 . 队列中的每条消息都将由一个且仅一个消费者处理 .

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

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

    作为Java EE Tutorial states

    消息消费消息传递产品本质上是异步的:消息的 生产环境 和消费之间没有基本的时序依赖性 . 但是,JMS规范更准确地使用了这个术语 . 可以通过以下两种方式之一来消息消息:同步:订阅者或接收者通过调用receive方法显式地从目标获取消息 . 接收方法可以阻止,直到消息到达,或者如果消息未在指定的时间限制内到达,则可以超时 . 异步:客户端可以向消费者注册消息监听器 . 消息侦听器类似于事件侦听器 . 每当消息到达目的地时,JMS提供者通过调用侦听器的onMessage方法来传递消息,该方法对消息的内容起作用 .

    因为您使用 MessageListener (根据定义 asynchronous ),您不会阻止队列或其后续处理 .

    同样来自the tutorial如下:

    使用会话Bean生成和同步接收消息生成消息或同步接收消息的应用程序可以使用会话Bean来执行这些操作 . 使用带有会话Bean的JMS API的应用程序中的示例使用无状态会话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一书,其中详细介绍了与产品/技术无关的消息传递概念 .

相关问题