带有setRollbackOnly的JMS和MDB [英] JMS and MDB with setRollbackOnly

查看:145
本文介绍了带有setRollbackOnly的JMS和MDB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java类,该类使用队列中的消息,并向某些URL发送HTTP调用.我已经在Google以及stackoverflow上进行了一些搜索(如果我错过了任何提及此问题的消息来源,我非常抱歉),但是找不到有关setRollbackOnly调用的详细信息.

I have a java class which consumes messages from a queue, sending HTTP calls to some urls. I have made some search on google and also on stackoverflow (and really sorry if i have missed any sources mentioning about the problem) but couldnt find anything in details about setRollbackOnly call.

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

My question is... in case I rollback, the message which is consumed from the queue will be blocking the rest of the queue and will be looping until it is processed successfully or it will be requeued at the end of the current queue?

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

My code which I use for consuming from the queue and sending HTTP calls is below and the whole application is running on Glassfish server:


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();
    }
  }
}

推荐答案

这是JMS/消息基础知识.

This is fundamental JMS/messaging knowledge.

队列实现负载平衡"方案,从而使消息进入队列并由一个使用者中断处理.使用者数量的增加会增加该队列处理的潜在吞吐量.队列中的每条消息都将由一个且只有一个使用者处理.

Queues implement "load balancing" scenarios, whereby a message hits a queue and is dequed to be processed by one consumer. Increasing the number of consumers increases potential throughput of that queue's processing. Each message on a queue will be processed by one and only one consumer.

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

Topics provide publish-subscribe semantics: all consumers of a topic will receive the message that is pushed to the topic.

考虑到这一点,一旦消息出队列并(以事务方式)传递给使用者,则它绝不会阻塞队列中的其余部分(如果它是异步的)(与MDB一样).

With that in mind, once a message is dequed and handed (transactionally) to a consumer, it is by no means blocking the rest of the queue if it is asynchronous (as is the case with MDBs).

Java EE教程状态:

消息消耗

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

Messaging products are inherently asynchronous: There is no fundamental timing dependency between the production and the consumption of a message. However, the JMS specification uses this term in a more precise sense. Messages can be consumed in either of two ways:

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

Synchronously: A subscriber or a receiver explicitly fetches the message from the destination by calling the receive method. The receive method can block until a message arrives or can time out if a message does not arrive within a specified time limit.

异步:客户端可以向使用者注册消息侦听器.消息侦听器类似于事件侦听器.每当消息到达目的地时,JMS提供者都会通过调用侦听器的onMessage方法来传递消息,该方法将根据消息的内容进行操作.

由于使用的是定义为异步MessageListener,因此不会阻塞队列或其后续处理.

Because you use a MessageListener which is by definition asynchronous, you are not blocking the queue or its subsequent processing.

也来自该教程如下:

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

Using Session Beans to Produce and to Synchronously Receive Messages

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

An application that produces messages or synchronously receives them can use a session bean to perform these operations. The example in An Application That Uses the JMS API with a Session Bean uses a stateless session bean to publish messages to a topic.

由于阻塞的同步接收占用了服务器资源,因此在企业Bean中使用这样的接收调用不是一个好的编程习惯.而是使用定时同步接收,或使用消息驱动的bean异步接收消息.有关阻止和定时同步接收的详细信息,请参阅编写客户端以获取同步接收示例.

Because a blocking synchronous receive ties up server resources, it is not a good programming practice to use such a receive call in an enterprise bean. Instead, use a timed synchronous receive, or use a message-driven bean to receive messages asynchronously. For details about blocking and timed synchronous receives, see Writing the Clients for the Synchronous Receive Example.

对于消息失败,这取决于队列的配置方式.您可以设置错误队列(对于诸如Glassfish或Weblogic之类的容器),将失败的消息推送到该队列以供以后检查.就您而言,您正在使用setRollbackOnly 这样处理:

As for message failure, it depends on how your queue is configured. You can set error-queues (in the case of containers like Glassfish or Weblogic) that failed messages are pushed to for later inspection. In your case, you're using setRollbackOnly which is handled thus:

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

7.1.2 Coding the Message-Driven Bean: MessageBean.java

消息驱动的Bean类MessageBean.java实现了 setMessageDrivenContext,ejbCreate,onMessage和ejbRemove方法. onMessage方法几乎与TextListener.java的方法相同, 将传入的消息强制转换为TextMessage并显示文本.这 唯一的不同是它称 如果发生异常,则使用MessageDrivenContext.setRollbackOnly方法. 此方法回滚事务,以便消息将是 重新交付.

The message-driven bean class, MessageBean.java, implements the methods setMessageDrivenContext, ejbCreate, onMessage, and ejbRemove. The onMessage method, almost identical to that of TextListener.java, casts the incoming message to a TextMessage and displays the text. The only significant difference is that it calls the MessageDrivenContext.setRollbackOnly method in case of an exception. This method rolls back the transaction so that the message will be redelivered.

我建议您阅读Java EE教程以及有关消息传递概念的 Enterprise Integration Patterns 一书.详细信息也与产品/技术无关.

I recommend you read the Java EE Tutorial as well as the Enterprise Integration Patterns book which covers messaging concepts in good detail that's also product/technology-agnostic.

这篇关于带有setRollbackOnly的JMS和MDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆