2011-12-13 224 views
6

在JMS API文档,它表示:JMS队列接收消息?

public Message receive() throws JMSException 

接收此消息消费者产生的下一个消息 。该调用将无限期地阻止 ,直到生成消息或直到此消息使用者关闭。

如果这个接收是在一个事务中完成的,那么消费者会保留这个消息直到事务提交。

这里我有三个问题: 1.在代码中,我们是否需要while循环来接收消息?像:

while(true){ 
    Message msg = queue.receive(); 
    .... 
} 
  • 什么是事务设置?如何提交交易?像这样:

    boolean transacted = false; 
    session = connection.createQueueSession(transacted, Session.AUTO_ACKNOWLEDGE); 
    
  • receiveNoWait()有事务支持吗?如何使用它 ?

  • 感谢

    回答

    3
    1. 如果你要使用接收,那么你将需要某种形式的循环收到的第一个后继续接收消息。请记住,您还可以设置messagelistener并通过回调方法获取收到的消息异步,而不必阻止。

    2. 默认情况下,事务通常设置为AUTO_ACKNOWLEDGE,这意味着一旦从队列中取消消息,事务就消失了,无法回滚。如果要设置事务,则需要将会话设置为事务处理,并将方法设置为SESSION_TRANSACTED。在会话上调用commit()时,消息将在队列上得到确认。

    3. 如果您正确设置确认模式并且您在会话中使用commit()和rollback(),receiveNoWait()可以具有事务支持。

    如果我是你,我会创建一个MessageListener,而不必担心旋转线程来轮询接收方法。请记住,创建会话后将启动隐式事务。

    public class JmsAdapter implements MessageListener, ExceptionListener 
    { 
        private ConnectionFactory connFactory = null; 
        private Connection conn = null; 
        private Session session = null; 
    
        public void receiveMessages() 
        { 
         try 
         { 
          this.session = this.conn.createSession(true, Session.SESSION_TRANSACTED); 
    
          this.conn.setExceptionListener(this); 
    
          Destination destination = this.session.createQueue("SOME_QUEUE_NAME"); 
    
          this.consumer = this.session.createConsumer(destination); 
    
          this.consumer.setMessageListener(this); 
    
          this.conn.start(); 
         } 
         catch (JMSException e) 
         { 
          //Handle JMS Exceptions Here 
         } 
        } 
    
        @Override 
        public void onMessage(Message message) 
        { 
         try 
         { 
          //Do Message Processing Here 
    
          //Message sucessfully processed... Go ahead and commit the transaction. 
          this.session.commit(); 
         } 
         catch(SomeApplicationException e) 
         { 
          //Message processing failed. 
          //Do whatever you need to do here for the exception. 
    
          //NOTE: You may need to check the redelivery count of this message first 
          //and just commit it after it fails a predefined number of times (Make sure you 
          //store it somewhere if you don't want to lose it). This way you're process isn't 
          //handling the same failed message over and over again. 
          this.session.rollback() 
         } 
        } 
    } 
    
    +0

    如果使用事务,它会减小性能吗? – user595234

    +0

    事务在JMS服务器上施加开销,因为它在提交之前无法释放消息。 – gregwhitaker

    +0

    您还可以查看以下关于JMS与Java的一些性能建议:http://www.precisejava.com/javaperf/j2ee/JMS.htm – gregwhitaker