JMS队列接收消息?

use*_*234 7 java jms

在JMS API文档中,它说:

public Message receive() throws JMSException
Run Code Online (Sandbox Code Playgroud)

接收为此消息使用者生成的下一条消息.此调用将无限期地阻塞,直到生成消息或此消息使用者关闭为止.

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

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

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

    boolean transacted = false;
    session = connection.createQueueSession(transacted, Session.AUTO_ACKNOWLEDGE);
    
    Run Code Online (Sandbox Code Playgroud)
  2. receiveNoWait()有事务支持吗?如何使用它 ?

谢谢

gre*_*ker 3

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

  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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)