使用多线程侦听器处理JMS事务和重新交付

使用多线程侦听器处理JMS事务和重新交付,jms,advanced-queuing,Jms,Advanced Queuing,我正在使用JMS在Java1.8SE环境中处理消息。这些消息来自Oracle高级队列。因为处理消息可能需要一段时间,所以我决定在MessageHandler对象中设置一个由5个工作线程组成的池,以便多个线程可以同时处理消息。我想有没有重复的邮件传递保证交付 我用 创建队列会话。我使用下面的代码来处理传入的消息。基本上,onMessage生成一个处理消息的线程 public class JmsQueueListener implements MessageListener { /** A

我正在使用JMS在Java1.8SE环境中处理消息。这些消息来自Oracle高级队列。因为处理消息可能需要一段时间,所以我决定在MessageHandler对象中设置一个由5个工作线程组成的池,以便多个线程可以同时处理消息。我想有没有重复的邮件传递保证交付

我用

创建队列会话。我使用下面的代码来处理传入的消息。基本上,onMessage生成一个处理消息的线程

public class JmsQueueListener implements MessageListener
{
    /** A pool of worker threads for handling requests. */
    private final ExecutorService pool;

    OracleJmsQueue queue;

    public void onMessage(Message msg)
    {
        pool.execute(new MessageHandler(msg));
        // can't commit here - the thread may still be processing
    }

    /**
     * This class provides a "worker thread" for processing a message
     * from the queue.
     */
    private class MessageHandler implements Runnable {

        /**
         * The message to process
         */
        Message message;

        /**
         * The constructor stores the passed in message as a field
         */
        MessageHandler(Message message) {
            this.message = message;
        }

        /**
         * Processes the message provided to the constructor by
         * calling the appropriate business logic.
         */
        public void run() {
            QueueSession queueSession = queue.getQueueSession();
            try {
                String result = requestManager.processMessage(message);

                if (result != null) {
                    queueSession.commit();
                }
                else {
                    queueSession.rollback();
                }
            }
            catch (Exception ex) {
                try {
                    queueSession.rollback();
                }
                catch (JMSException e) {
                }
            }
        }
    }   //  class MessageHandler
我的问题是,我不知道如何向发起队列指示处理是否已成功完成。我无法在onMessage结束时提交,因为线程可能尚未完成处理。我认为我目前有提交和回滚的地方也没有任何好处。例如,如果5个工作线程处于各种完成状态,那么正在提交的队列会话的状态是什么


我想我一定缺少了一些关于如何以多线程方式处理JMS的基本概念。任何帮助都将不胜感激。

您使用的是异步消息处理,因此,除非您实现了一种方法来确保每个消息处理按时间顺序完成,否则您将在最近的消息处理之后完成旧消息处理。那么为什么要使用消息服务呢

解决问题的一个简单方法是在onMessage方法的末尾提交,并在messageHandler的主体中,在出现错误时将消息重新排队。但是,如果重新排队本身失败,此解决方案可能会有问题

public class JmsQueueListener implements MessageListener
{
    /** A pool of worker threads for handling requests. */
    private final ExecutorService pool;

    OracleJmsQueue queue;

    public void onMessage(Message msg)
    {
        pool.execute(new MessageHandler(msg));
        // can't commit here - the thread may still be processing
    }

    /**
     * This class provides a "worker thread" for processing a message
     * from the queue.
     */
    private class MessageHandler implements Runnable {

        /**
         * The message to process
         */
        Message message;

        /**
         * The constructor stores the passed in message as a field
         */
        MessageHandler(Message message) {
            this.message = message;
        }

        /**
         * Processes the message provided to the constructor by
         * calling the appropriate business logic.
         */
        public void run() {
            QueueSession queueSession = queue.getQueueSession();
            try {
                String result = requestManager.processMessage(message);

                if (result != null) {
                    queueSession.commit();
                }
                else {
                    queueSession.rollback();
                }
            }
            catch (Exception ex) {
                try {
                    queueSession.rollback();
                }
                catch (JMSException e) {
                }
            }
        }
    }   //  class MessageHandler