Java Weblogic JMS客户端-在单个事务中从多个队列读取

Java Weblogic JMS客户端-在单个事务中从多个队列读取,java,jms,weblogic,weblogic11g,Java,Jms,Weblogic,Weblogic11g,在使用WebLogic 11g(WebLogic Server 10.3.6.0)的WebLogic JMS客户端(wlthin3client.jar)从单个事务中的多个JMS队列读取消息时,我遇到了一个问题。我尝试从队列Q1读取第一条消息,然后,如果该消息满足某些要求,则从队列Q2读取其他消息(如果当时可用) 我期望在提交事务后,两条消息都会从Q1和Q2中消失。在回滚的情况下,消息应保留在Q1和Q2中 我的第一种方法是使用异步队列接收器读取Q1,然后在需要时同步读取Q2: void run()

在使用WebLogic 11g(WebLogic Server 10.3.6.0)的WebLogic JMS客户端(wlthin3client.jar)从单个事务中的多个JMS队列读取消息时,我遇到了一个问题。我尝试从队列Q1读取第一条消息,然后,如果该消息满足某些要求,则从队列Q2读取其他消息(如果当时可用)

我期望在提交事务后,两条消息都会从Q1和Q2中消失。在回滚的情况下,消息应保留在Q1和Q2中

我的第一种方法是使用异步队列接收器读取Q1,然后在需要时同步读取Q2:

void run() throws JMSException, NamingException {
    QueueConnectionFactory cf = (QueueConnectionFactory) ctx.lookup(connectionFactory);

    // create connection and session
    conn = cf.createQueueConnection();
    session = conn.createQueueSession(true, Session.SESSION_TRANSACTED);
    Queue q1 = (Queue) ctx.lookup(queue1);

    // setup async receiver for Q1
    QueueReceiver q1Receiver = session.createReceiver(q1 );
    q1Receiver.setMessageListener(this);

    conn.start();

    // ...
    // after messages are processed
    conn.close();
}

@Override
public void onMessage(Message q1msg) {
    try {
        QueueReceiver q2receiver = session.createReceiver(queue2);
        if(shouldReadFromQ2(q1msg)){      
           // synchronous receive from Q2
           Message q2msg = q2receiver.receiveNoWait();
           process(q2msg);
        }
        session.commit();
    } catch (JMSException e) {
        e.printStackTrace();
    } finally {
        q2receiver.close();
    }
}
不幸的是,即使我发出了一个
session.commit()
,来自Q1的消息仍然没有提交。在连接或接收器关闭之前,它处于
receive
状态。然后,当它进入延迟状态时,它似乎被回滚

其他意见:

  • 如果Q2为空且无任何内容可从中读取,则Q1消息已正确提交
  • 当我以类似的嵌套方式为Q1和Q2使用同步API时,问题不会出现。因此,如果我使用q1Receiver.receiveNoWait()一切正常
  • 若我以类似的嵌套方式为Q1和Q2使用异步API,那个么只调用Q1消息侦听器,并在Q1上进行提交。但根本不调用Q2消息侦听器,也不提交Q2(消息卡在
    receive
    /
    delayed
    )中)

  • 我是不是误用了API?或者这是一个WLS JMS错误?如何将从多个队列读取与异步API结合起来

    原来这是一个WLS JMS。 bug状态表示它已修复,但我不相信这一点-使用此修复的WLS 11g修补程序不起作用(请参阅)

    Oracle表示,之所以会出现这种情况,是因为两种不同的传递机制(同步消息和异步消息)并不是为在同一个会话中协同工作而设计的

    解决此问题的最简单方法是在需要在单个会话中处理多个队列的情况下使用同步API(轮询)。我决定采用这种方法

    oracle建议的另一个选项是将UserTransactions用于两个不同的会话,一个会话用于异步使用者,另一个会话用于同步使用者。不过我没有测试