Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Управляемые контейнером транзакции

В Enterprise-бине с управляемыми контейнером транзакциями границы транзакций устанавливаются контейнером EJB. Управляемые контейнером транзакции можно использовать с любым типом Enterprise-бина: сессионным или управляемым сообщениями. Управляемые контейнером транзакции упрощают разработку, поскольку код Enterprise-бина явно не отмечает границы транзакции. В коде отсутствуют операторы, которые начинают и заканчивают транзакцию. По умолчанию, если разграничение транзакции не указано, Enterprise-бины используют транзакцию, управляемую контейнером.

Как правило, контейнер начинает транзакцию непосредственно перед запуском метода Enterprise-бина и фиксирует транзакцию непосредственно перед завершением метода. Каждый метод может быть связан с одной транзакцией. Вложенные или множественные транзакции в методе не разрешены.

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

Enterprise-бины, использующие разграничение транзакций, управляемое контейнером, не должны использовать методы управления транзакциями, которые мешают разграничению транзакций контейнером. Примерами таких методов являются методы commit, setAutoCommit и rollback для java.sql.Connection или методы commit и rollback для javax.jms.Session. Если вам требуется контроль над разграничением транзакций, вы должны использовать разграничение транзакций, управляемое приложением.

Enterprise-бины, использующие разграничение управляемых контейнером транзакций, также не должны использовать интерфейс javax.transaction.UserTransaction.

Атрибуты транзакции

Атрибут транзакции контролирует область действия транзакции. На рисунке 54-1 показано, почему ею важно управлять. На диаграмме method-A начинает транзакцию, а затем вызывает method-B у Bean-2. Когда method-B выполняется, он запускается в рамках транзакции, запущенной method-A, или выполняется в новой транзакции? Ответ зависит от атрибута транзакции method-B.

Рисунок 54-1 Область действия транзакции

Диаграмма, показывающая транзакцию между двумя компонентами.

Атрибут транзакции может иметь одно из следующих значений:

  • Required

  • RequiresNew

  • Mandatory

  • NotSupported

  • Supports

  • Never

Атрибут Required

Если клиент работает в транзакции и вызывает метод Enterprise-бина, метод выполняется в транзакции клиента. Если клиент не связан с транзакцией, контейнер запускает новую транзакцию перед запуском метода.

Атрибут Required является неявным атрибутом транзакции для всех методов Enterprise-бина, работающих с разграничением транзакций, управляемым контейнером. Обычно атрибут Required не устанавливается, если не нужно переопределять другой атрибут транзакции. Поскольку атрибуты транзакции являются декларативными, их легко можно изменить позже.

Атрибут RequiresNew

Если клиент работает в транзакции и вызывает метод Enterprise-бина, контейнер выполняет следующие шаги:

  1. Приостанавливает транзакцию клиента

  2. Запускает новую транзакцию

  3. Делегирует вызов метода

  4. Возобновляет транзакцию клиента после завершения метода

Если клиент не связан с транзакцией, контейнер запускает новую транзакцию перед запуском метода.

Атрибут requireNew используется, если нужна уверенность, что метод всегда выполняется в новой транзакции.

Атрибут Mandatory

Если клиент работает в транзакции и вызывает метод Enterprise-бина, метод выполняется в транзакции клиента. Если клиент не связан с транзакцией, контейнер выбрасывает исключение TransactionRequiredException.

Атрибут Mandatory используется, если метод Enterprise-бина должен использовать транзакцию клиента.

Атрибут NotSupported

Если клиент работает в транзакции и вызывает метод Enterprise-бина, контейнер приостанавливает транзакцию клиента перед вызовом метода. После завершения метода контейнер возобновляет транзакцию клиента.

Если клиент не связан с транзакцией, контейнер не запускает новую транзакцию перед запуском метода.

Атрибут NotSupported используется для методов, которые не требуют транзакций. Поскольку с транзакциями связаны накладные расходы, этот атрибут может повысить производительность.

Атрибут Supports

Если клиент работает в транзакции и вызывает метод Enterprise-бина, метод выполняется в транзакции клиента. Если клиент не связан с транзакцией, контейнер не запускает новую транзакцию перед запуском метода.

Поскольку транзакционное поведение метода может отличаться, следует использовать атрибут Supports с осторожностью.

Атрибут Never

Если клиент работает в транзакции и вызывает метод Enterprise-бина, контейнер генерирует RemoteException. Если клиент не связан с транзакцией, контейнер не запускает новую транзакцию перед запуском метода.

Обзор атрибутов транзакции

Таблица 54-1 суммирует влияние атрибутов транзакции. Обе транзакции T1 и T2 управляются контейнером. Транзакция T1 связана с клиентом, который вызывает метод в Enterprise-бине. В большинстве случаев клиент — это другой Enterprise-бин. Транзакция T2 запускается контейнером непосредственно перед выполнением метода.

В последнем столбце таблицы 54-1 слово «None» означает, что бизнес-метод не выполняется в транзакции, управляемой контейнером. Однако вызовы базы данных в таком бизнес-методе могут управляться менеджером транзакций системы управления базами данных.

Таблица 54-1 Атрибуты транзакции и область действия

Атрибут транзакции

Транзакция клиента

Транзакция бизнес-метода

Required

None

T2

Required

T1

T1

RequiresNew

None

T2

RequiresNew

T1

T2

Mandatory

None

Error

Mandatory

T1

T1

NotSupported

None

None

NotSupported

T1

None

Supports

None

None

Supports

T1

T1

Never

None

None

Never

T1

Error

Установка атрибутов транзакции

Атрибуты транзакции задаются путём аннотирования класса или метода Enterprise-бина аннотацией javax.ejb.TransactionAttribute и установки для неё одной из констант javax.ejb.TransactionAttributeType.

Если аннотировать класс Enterprise-бина с помощью @TransactionAttribute, указанный TransactionAttributeType будет применён ко всем бизнес-методам в классе. При аннотирования бизнес-метода с помощью @TransactionAttribute TransactionAttributeType применяется только к этому методу. Если аннотацией @TransactionAttribute аннотированы и класс, и метод, атрибут TransactionAttributeType метода переопределяет атрибут TransactionAttributeType класса.

Константы TransactionAttributeType, перечисленные в таблице 54-2, инкапсулируют атрибуты транзакции, описанные ранее в этом разделе.

Таблица 54-2 Константы TransactionAttributeType

Атрибут транзакции Константа TransactionAttributeType

Required

TransactionAttributeType.REQUIRED

RequiresNew

TransactionAttributeType.REQUIRES_NEW

Mandatory

TransactionAttributeType.MANDATORY

NotSupported

TransactionAttributeType.NOT_SUPPORTED

Supports

TransactionAttributeType.SUPPORTS

Never

TransactionAttributeType.NEVER

В следующем фрагменте кода показано, как использовать аннотацию @TransactionAttribute:

@TransactionAttribute(NOT_SUPPORTED)
@Stateful
public class TransactionBean implements Transaction {
...
    @TransactionAttribute(REQUIRES_NEW)
    public void firstMethod() {...}

    @TransactionAttribute(REQUIRED)
    public void secondMethod() {...}

    public void thirdMethod() {...}

    public void fourthMethod() {...}
}

В этом примере атрибут транзакции класса TransactionBean был установлен в NotSupported, firstMethod был установлен в requireNew, и secondMethod был установлен в Required. Поскольку @TransactionAttribute для метода переопределяет @TransactionAttribute для класса, вызовы firstMethod создадут новую транзакцию и вызов secondMethod будет либо запущен в текущей транзакции, либо начнёт новую транзакцию. Вызовы thirdMethod и fourthMethod происходят не в транзакции.

Откат транзакции, управляемой контейнером

Существует два способа откатить транзакцию, управляемую контейнером. Во-первых, если выдаётся системное исключение, контейнер автоматически откатит транзакцию. Во-вторых, вызывая метод setRollbackOnly интерфейса EJBContext, метод бина сигнализирует контейнеру откатить транзакцию. Если бин генерирует исключение приложения, откат не выполняется автоматическим, но может быть инициирован вызовом setRollbackOnly.

Синхронизация переменных объекта сессионного бина

Необязательный интерфейс SessionSynchronization позволяет объектам сессионного компонента с сохранением состояния получать уведомления о синхронизации транзакций. Например, вы можете синхронизировать переменные объекта Enterprise-бина с соответствующими значениями в базе данных. Контейнер вызывает методы SessionSynchronization (afterBegin, beforeCompletion и afterCompletion) на каждом из основных этапов транзакции.

Метод afterBegin информирует объект о начале новой транзакции. Контейнер вызывает afterBegin непосредственно перед вызовом бизнес-метода.

Контейнер вызывает метод beforeCompletion после завершения бизнес-метода, но непосредственно перед фиксацией транзакции. Метод beforeCompletion является последней возможностью для сессионного компонента откатить транзакцию (путём вызова setRollbackOnly).

Метод afterCompletion указывает, что транзакция завершена. Этот метод имеет единственный параметр boolean, значение которого равно true, если транзакция была зафиксирована, и false, если был выполнен откат.

Методы, не разрешённые в транзакциях, управляемых контейнером

Недопустимо вызывать какой-либо метод, который может помешать разграничению транзакции, установленному контейнером. Следующие методы запрещены:

  • Методы commit, setAutoCommit и rollback для java.sql.Connection

  • Метод getUserTransaction для javax.ejb.EJBContext

  • Любой метод javax.transaction.UserTransaction

Однако допускается использовать эти методы для установки границ в управляемых приложением транзакциях.


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)