Изучаем Java EE 7 - [211]

Шрифт
Интервал

>··································propertyValue = "Auto-acknowledge"), 

>········@ActivationConfigProperty(propertyName··= "messageSelector", 

>··································propertyValue = "orderAmount BETWEEN 3 AND 7")

>})

>public class BillingMDB implements MessageListener {


>··@Inject

>··@JMSConnectionFactory("jms/javaee7/ConnectionFactory")

>··@JMSSessionMode(JMSContext.AUTO_ACKNOWLEDGE)

>··private JMSContext context;

>··@Resource(lookup = "jms/javaee7/Queue")

>··private Destination printingQueue;


>··public void onMessage(Message message) {

>····System.out.println("Сообщение получено: " + 

>·······················message.getBody(String.class));

>····sendPrintingMessage();

>··}


>··private void sendPrintingMessage() throws JMSException {

>····context.createProducer(). send(printingQueue, "Сообщение, было получено и снова отправлено");

>··}

>}

Этот MDB использует большинство понятий, изученных к данному моменту. Во-первых, он применяет аннотацию @MessageDriven для определения имени JNDI темы, которую слушает (mappedName = "jms/javaee7/Topic"). В этой же аннотации он определяет набор свойств, таких как режим подтверждения и селектор сообщений с использованием массива аннотаций @ActivationConfigProperty, и реализует интерфейс MessageListener и его метод onMessage().

Этот MDB также должен производить сообщения. Таким образом, в него внедряются два необходимых администрируемых объекта: фабрика соединений (с использованием JMSContext) и место назначения (очередь с именем jms/javaee7/Queue). Наконец, бизнес-метод, который посылает сообщения (метод sendPrintingMessage()), выглядит так, как вы видели ранее: создается объект типа JMSProducer и используется для создания и отправки текстового сообщения. Для лучшей читаемости обработка исключений была опущена во всем классе.

Транзакции

MDB — это разновидность EJB (для получения дополнительной информации см. главы 7 и 8). MDB могут использовать BMT или управляемые контейнером транзакции (CMT), они могут явно откатывать транзакции с помощью метода MessageDrivenContext.setRollbackOnly() и т. д. Однако у MDB есть некоторые особенности, на которых следует остановиться.

Говоря о транзакциях, мы всегда думаем о реляционных базах данных. Однако другие ресурсы, такие как системы обмена сообщениями, также могут быть транзакционными. Если две или более операции должны завершиться успехом или неудачей вместе, они образуют транзакцию (см. главу 9). Если рассматривать обмен сообщениями, то в случае отправки двух или более они должны быть отправлены успешно (фиксация) или неудачно (откат) вместе. Как это работает на практике? Ответ заключается в том, что сообщения не отправляются потребителям, пока транзакция не завершена. Контейнер начнет транзакцию перед вызовом метода onMessage() и закончит транзакцию по его возвращении (кроме случаев, когда транзакция помечена для отката с помощью метода setRollbackOnly()).

Хотя MDB являются транзакционными, они не могут выполняться в контексте транзакции клиента, так как клиента не имеют. Никто явно не вызывает методы MDB, они просто слушают место назначения и получают сообщения.

Контекст не передается от клиента к MDB, и аналогично транзакционный контекст клиента не может быть передан в методе onMessage(). В табл. 13.11 сравниваются сессионные компоненты, CMT и MDB.


Таблица 13.11. Транзакции MDB в сравнении с транзакциями сеансовых компонентов
Атрибут транзакцииСессионный компонентMDB
NOT_SUPPORTEDДаДа
REQUIREDДаДа
MANDATORYДаНет
REQUIRES_NEWДаНет
SUPPORTSДаНет
NEVERДаНет

В CMT MDB могут использовать аннотацию @javax.ejb.TransactionAttribute на бизнес-методах со следующими двумя атрибутами:

• REQUIRED (по умолчанию) — если MDB вызывает другие компоненты, контейнер вместе с вызовом передает контекст транзакции; контейнер пытается зафиксировать транзакцию, когда завершается метод слушателя сообщений;

• NOT_SUPPORTED — если MDB вызывает другие компоненты, контейнер не передает контекст транзакции вместе с вызовом.

Обработка исключений

Во фрагментах кода, приведенных в этой главе, обработка исключений была опущена, поскольку в JMS API она может быть слишком объемной. Классический API определяет двенадцать различных исключений, которые наследуются от типа javax.jms.JMSException. В упрощенном API определены десять исключений времени выполнения, которые наследуются от javax.jms.JMSRuntimeException.

Важно отметить, что JMSException является проверенным исключением (см. главу 9 (обсуждение исключений приложения в разделе «Обработка исключений»)), а JMSRuntimeException — непроверенным. Спецификация EJB описывает два типа исключений:

• исключения приложения — проверенные исключения, которые наследуются от класса Exception и не вызывают отката контейнера;

• системные исключения — непроверенные исключения, которые наследуются от класса RuntimeException и вызывают откат контейнера.

Генерация исключения JMSRuntimeException вызовет откат контейнера, а генерация JMSException — нет. Если выполнить откат необходимо, должен быть явно вызван метод setRollBackOnly() или сгенерировано системное исключение (например, EJBException):


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.