1

我正在尝试在 onMessage 方法中使用消息,因为我希望在一个事务中使用多条消息以提高性能。

Message message = consumer.receive();

返回空值。它甚至不会阻塞。买为什么?它必须被阻止,直到它收到消息,不是吗?

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {

    QueueConnection queueConnection = null;     
    queueConnection = qcf.createQueueConnection();
    queueConnection.start();
    queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    Queue queue = queueSession.createQueue(sessionConnParams.toString());
    consumer = queueSession.createConsumer(queue);

    // it works in cycle
    System.out.println("before receive");
    Message message = consumer.receive();
    System.out.println("after receive");
    if (message == null) {
       System.out.println("no messages");
       return;
    }

   // process message

   } catch (Exception e) {
     // process exception
   } finally {
     // close objects
   }
}
4

2 回答 2

1

在我看来,在 onMessage() 中创建另一个接收器并不是一个好主意。EJB 规范不建议在 OnMessage 方法中启动线程。

在一个事务中接收多条消息不会提高性能。性能取决于多种因素

onMessage1)方法处理消息所花费的时间。

2) 消息传递提供者传递消息的速度

3) 网络

4) 硬件

为了提高性能,您可以考虑并行运行多个 MDB。还要查看您正在使用的消息传递提供程序的性能调整。

这是IBM提供的一个有用链接

于 2012-06-24T15:21:34.910 回答
0

如果您遇到全局事务,我认为您不太可能让 JMS 做您想做的事情。如果你使用

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)

这将强制应用程序服务器在未指定的事务上下文中运行。这意味着什么完全取决于您使用的应用程序服务器。如果您使用的是 Websphere Application Server,这意味着 bean 在事务之外运行,因此发送和接收消息等操作会按照您的预期进行。其他应用程序服务器可能会以不同的方式处理此问题 - 请阅读文档。无论如何,这样做可能是个坏主意。您正在针对应用程序服务器工作。

JMS 规范定义了一种批量传递消息的机制。IBM Websphere MQ 将此预读称为http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/index.jsp?topic=%2Fcom.ibm.mq.csqzaw.doc%2Fjm41130_.htm,它允许一次从队列中读取多条消息,并一个接一个地传递给应用程序。其他 JMS 实现可能支持类似的东西。

但最终,如果您的应用程序要求始终按顺序处理消息,那么您将不得不处理在处理下一条消息之前提交每条消息的开销。几乎可以肯定,提交开销远大于将消息传递到 MDB 的开销。试图破解一些东西来读取 MDB 中的额外消息不会让你解决这个问题。如果这对您来说是个问题,您可能应该考虑对应用程序进行更改,以便能够乱序处理消息。

于 2012-08-31T04:27:34.917 回答