четверг, 28 июля 2011 г.

Транзакции, управляемые контейнером EJB.

Enterprise beans поддерживают два типа управления транцакциями: container-managed или bean-managed. По умолчанию, если явно не задано, то используется первый, с которым я сегодня разбирался и хочу рассказать.

По сути, это просто заметки, сделанные с документации Java EE 6 Tutorial.

Container-managed транзакции упрощают разработку, т.к. за границами транзакции следит контейнер EJB. Транзакции, управляемые контейнером, могут работать как с session, так и с message-driven бинами.

Транзакция автоматически стартует перед началом запуска метода в бине и заканчивается по завершении этого метода. Container-managed транзакции не поддерживают вложенные и мульти-транзакции.

Container-managed транзакция не должна использовать методы управления транзакциями, т. к. эти операции возложены на контейнер EJB.

Существует возможность управления запуском транзакций для ejb-методов. Если внутри транцакции вызывается метод другого бина, то как должна вести себя транзакция с этим методом? На этот метод можно поставить различные ограничители принадлежности к текущей транзакции, при помощи аннотации @TransactionAttribute:
  • REQUIRED - если метод запущен внутри транзакции, то он является частью транзакции. Если запущен вне транзакции, то в нем стартует новая транзакция.
  • REQUIRES_NEW - если метод запускается внутри транзакции, то она останавливается, запускается новая, отрабатывается, а затем продолжает работу первая. Если метод запускается самостоятельно, то просто стартует новая транзакция. Данный модификатор служит для того, что бы быть уверенным, что всегда будет запущена новая транзакция.
  • MANDATORY - если метод запущен внутри транзакции, то он является её частью. Если же запускается вне транзакции, то бросается исключение TransactionRequiredException.
  • NOT_SUPPORTED - если метод запускается внутри транзакции, то на время работы метода транзакция останавливается, пока не отработается метод, травзакция в которм не стартуетс, затем транзакция продолжает работу. Если метод запускается вне транзакции, то транзакция в нем не стартует. Этот атрибут увеличивает производительность, т.к. транзакции связаны с дополнительными нагрузками.
  • SUPPORTS - если внутри транзакции, то является частью транзакции, если запускается самостоятельно, то транзакция не стартует.
  • NEVER - Если внутри транзакции, то бросается исключение RemoteException, если вне транзакции, то метод запускается без старта транзакции.
Аннотация  @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() {...}
}
Если во время работы транзакции бросается системное исключение, то автоматом происходит откат транзакции. Управление откатом при эксепшенах приложения задается в методе setRollbackOnly интерфейса EJBContext, который обрабатывается с REQUIRED, REQUIRES_NEW, или MANDATORY атрибутами транзакции. Если данный метод не будет запущен — транзакция завершится успешно:

public void transferToSaving(double amount) throws
InsufficientBalanceException {
    checkingBalance -= amount;
    savingBalance += amount;
    try {
        updateChecking(checkingBalance);
        if (checkingBalance < 0.00) {
            context.setRollbackOnly();
            throw new InsufficientBalanceException();
        }
        updateSaving(savingBalance);
    } catch (SQLException ex) {
        throw new EJBException
        ("Transaction failed due to SQLException: "
        + ex.getMessage());
    }
}
Session Beans поддерживают не обязательный интерфейс SessionSynchronization, который позволяет автоматически запускать методы на разных этапах выполнения транзакции: afterBegin, beforeCompletion, and afterCompletion. Первый может уведомлять сущность, что транзакция стартовала, второй запускается перед коммитом - последняя возможность сделать роллбек. Третий уведомляет, что транзакция выполнена и имеет только один булевый параметр со значением - true, если транзакция закоммичена или если роллбек - false

в container-managed транзакциях существуют запрещенные методы, т.к. могут пересекаться с границами текущей транзакции:
  • commit, setAutoCommit, и rollback методы класса java.sql.Connection
  • getUserTransaction метод класса javax.ejb.EJBContext
  • любой метод класса javax.transaction.UserTransaction

Комментариев нет:

Отправить комментарий