У меня проблема при чтении сообщений из нескольких очередей JMS в одной транзакции с использованием клиента WebLogic JMS (wlthin3client.jar) из WebLogic 11g (WebLogic Server 10.3.6.0). Я пытаюсь прочитать сначала одно сообщение из очереди 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
, пока соединение или приемник не будут закрыты. Тогда, похоже, происходит откат, так как он получает состояние delayed
.
Другие наблюдения:
- Сообщение Q1 корректно фиксируется, если Q2 пусто и нечего с него читать.
- Проблема не возникает, когда я использую синхронный API похожим, вложенным способом для Q1 и Q2. Так что, если я использую
q1Receiver.receiveNoWait()
все в порядке.
- Если я использую асинхронный API похожим, вложенным способом для Q1 и Q2, то вызывается только прослушиватель сообщений Q1, а коммит работает в Q1. Но приемник сообщений Q2 вообще не вызывается, а Q2 не фиксируется (сообщение застряло в
receive
/ delayed
).
Я как-то неправильно использую API? Или это ошибка WLS JMS? Как совместить чтение из нескольких очередей с асинхронным API?