Использование вручную сообщений в методе onMessage MDB
Я пытаюсь использовать сообщения в методе 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
}
}
2 ответа
По моему мнению, создание другого получателя в onMessage() не очень хорошая идея. Спецификации EJB не рекомендуют запускать потоки в методах OnMessage.
Получение нескольких сообщений в одной транзакции не приведет к повышению производительности. Производительность зависит от нескольких факторов
1) Время, затраченное на onMessage
способ обработки сообщения.
2) Как быстро поставщик сообщений доставляет сообщения
3) Сеть
4) Аппаратное обеспечение
Для повышения производительности вы можете рассмотреть возможность параллельного запуска нескольких MDB. Также посмотрите на настройку производительности провайдера обмена сообщениями, который вы используете.
Вот одна полезная ссылка от IBM
Я думаю, что вы вряд ли заставите 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 не поможет вам. Если это проблема для вас, вы, вероятно, должны попытаться внести изменения в приложение, чтобы иметь возможность обрабатывать сообщения не по порядку.