Как отправить несколько сообщений JMS в блоках (каждое в новой транзакции) - PullRequest
0 голосов
/ 04 июня 2011

В моем веб-приложении Java EE 6 достигнуто максимальное количество сообщений JMS, которые можно отправить за одну транзакцию, и мне нужно сделать это за несколько транзакций.Что было бы лучшим способом сделать это, когда транзакции управляются контейнером?Можно ли использовать один и тот же MessageProducer в разных транзакциях (используя метод EJB, помеченный @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW))

Я использую Glassfish v3 и OpenMQ.

Проблема с максимальнымсообщений в OpenMQ рассматривается в этом вопросе SO Максимальное количество сообщений, отправляемых в очередь в OpenMQ? .

Ответы [ 2 ]

1 голос
/ 04 июня 2011

Если вы не можете найти способ выполнить это с помощью управляемых контейнером транзакций на сервере приложений и не хотите использовать программные транзакции, вы можете рассмотреть возможность использования корпоративных интеграционных моделей Aggregator и / или Splitter.

В вашем источнике объедините ваши отдельные сообщения или объекты в одно составное сообщение. На стороне потребителя выделите составное сообщение для соответствующей обработки.

0 голосов
/ 05 июня 2011

@ Тео: отлично.Таким образом, в основном ваш текущий бизнес-поток выглядит следующим образом: -

Работа с интерфейсом (JSF UI) -> Уровень EJB (транзакция начинается) ---> публикация сообщений в FINAL QUEUE.

Теперь вот один из способов решения вашей проблемы: - вы можете определить разделенную очередь между: - Таким образом, поток может быть

любым: - интерфейсная (JSF UI) операция--> EJB-слой -> SPLIT QUEUE ---> MDB -> FINAL QUEUE
или, интерфейсная операция (JSF UI) -> SPLIT QUEUE ---> EJB-уровень -> FINAL QUEUE

Итак, основная идея заключается в том, что у вас есть n сообщений на один лимит транзакций и если у вас нет m сообщений для публикации, где m> n и m> 0;затем вы можете разделить m на блоки m \ n раз, введя разделенную очередь.Я сделал это в одном из моих проектов.Дайте мне знать, если у вас есть какие-либо вопросы.


@ Тео: Мне не очень понятно, что упомянул Асинкронос.Но вот что я имел в виду: - Вы выполняете операцию пользовательского интерфейса JSF (скажем так), 1000 сообщений JMS в вашу очередь FINAL.Теперь предположим, что на каждую транзакцию приходится 200 сообщений JMS.Что вы можете сделать, возможно, это: -

Хотя я не знаю полностью вашу модель данных / бизнес-поток, но вот краткий обзор.Позвольте мне предположить, что данные полезной нагрузки сообщения JMS поступают из набора таблиц, которые могут быть однозначно идентифицированы по идентификатору Un.Итак, у вас есть 1000 JMS-сообщений, которые должны быть опубликованы и идентифицированы как U1, U2 .... U1000.Таким образом, вы можете определить внутреннюю очередь SPLIT.В вашем Java-коде разделите 1000 идентификаторов на 200 блоков: so {U1 ... U200}, {U201 .... U400), {U401 ... U600), (U601, .. U800) и (U801... U1000).Вы можете опубликовать этот список идентификаторов в своей очереди разделения как полезную нагрузку Java.util.List.Вы можете определить очередь SPLIT прослушивания MDB с атрибутом транзакции REQUIRES-NEW.В коде MDB вы можете получить список идентификаторов и выполнить цикл for:

onMessage(Message m){
ObjectMessage objectMsg=(ObjectMessage) m;
java.util.List list=(List) objectMsg.getObject();
//open  a JMS session
for (String identifer : list){

//fetch data from DB for particular identifier.

//prepare output JMS payload for that particular identifier.

//publish JMS data onto FINAL queue
}

Надеюсь, это прояснится.

...