JMS队列接收消息?

时间:2011-12-13 16:21:40

标签: java jms

在JMS API文档中,它说:

public Message receive() throws JMSException
     

收到下一条消息   为此消息消费者制作。此调用无限期阻止   直到产生消息或直到此消息使用者关闭。

     

如果在事务中完成此接收,则使用者会保留该消息,直到事务提交为止。

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

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

    boolean transacted = false;
    session = connection.createQueueSession(transacted, Session.AUTO_ACKNOWLEDGE);
    
  2. receiveNoWait()有事务支持吗?怎么用?

  3. 由于

1 个答案:

答案 0 :(得分:3)

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

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

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

  4. 如果我是你,我会创建一个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()
            }
        }
    }