JMS - 从消息驱动的bean

时间:2015-08-03 15:41:36

标签: java ejb jms

我有一个消息驱动的bean,它接收来自队列的消息,处理它们,并将消息发送到另一个队列,

onMessage(Message inputMessage) {
    ... Message processing stuff...
    Connection connection = connectionFactory.createConnection();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Message outputMessage = session.createObjectMessage();
    outputMessage.setJMSCorrelationID(uniqueId);
    MessageProducer messageProducer = session.createProducer(outputQueue);
    messageProducer.send(outputMessage);
    ... Some more processing...
    QueueBrowser browser;
    browser = session.createBrowser(outputQueue, 
              String.format("JMSCorrelationID='%s'", uniqueId);
}

然后,我检查队列中的uniqueId,但该消息尚未出现在队列中。经过一番实验后,我发现只有在onMessage方法返回后才会在输出队列中显示消息。

这是一个错误吗?有没有办法立即发送outputMessage,这样我可以确定在messageProducer.send(outputMessage)之后消息确实出现在outputQueue中?

3 个答案:

答案 0 :(得分:2)

似乎是这里情况的另一面 - JMS rollback

您希望避免交易行为 - 立即发送与MDB交易无关。

阅读JavaEE 7 Connection.createSession()文档听起来似乎没有一种好方法可以创建与MDB的JTA事务分离的会话。 @ schtever使用session.commit()的答案的文档go so far as to say将不起作用。

如果所有这些都是真的,可能会创建一些执行JMS发送调用的其他方法。将此附加方法设置为事务NOT_SUPPORTEDREQUIRES_NEW

答案 1 :(得分:0)

session.commit();

之后发出messageProducer.send(outputMessage);

答案 2 :(得分:0)

When running in an application server the JMS operations enlist in any global transaction. The solution to this is to do the send in another transactional context. The simplest thing to do is move the send into an EJB with a transaction attribute of requires new.