Как распространяется UserTransaction?

У меня есть bean-компонент без сохранения состояния с транзакциями, управляемыми bean-компонентом, и такой метод:

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class ... {

    @Resource 
    private UserTransaction ut;
    @EJB 
    private OtherStatelessBeanLocal other;

    public void invokeSomeMethods() 
        ut.begin();
        ...

        // invoke other bean's methods here.
        other.method();

        ...
        ut.commit();

    }

}

Так как же UserTransaction распространяться на OtherStatelessBeanLocal фасоль?

3 ответа

Решение

UserTransaction объект - это объект, предоставленный контейнером, который обертывает доступ к вызовам API, которые контейнер использует внутри, в частности, javax.transaction.TransactionManager. TransactionManager имеет такие методы, как begin, commit, rollback а также javax.transaction.Transaction getTransaction()

Под прикрытием TransactionManager будет использовать ThreadLocal или подобный метод для отслеживания текущего состояния транзакции с потоком. ThreadLocals - это очень простые объекты, которые можно легко описать как static HashMap который использует имя потока в качестве ключа и объект по вашему выбору в качестве значения. Пока вы остаетесь в том же потоке, вы можете получить объект из любой точки цепочки вызовов. Это одна из причин, по которой нельзя запускать потоки в среде Java EE.

Распространение безопасности работает аналогичным образом, как и поиск JNDI, который магическим образом указывает на нужный модуль или компонент. java:comp/env Пространство имен. Суть в том, что вы не можете реализовать сервер приложений без ThreadLocals. Распространение звучит более активно, чем на самом деле, когда на самом деле это просто акт не покидания нити, чтобы контейнер и все вовлеченные в него все еще могли найти ваши "вещи".

Возвращаясь к терминам управления транзакциями, объект, который TransactionManager будет отслеживать в своем ThreadLocal, обычно реализует (прямо или косвенно) интерфейсы Transaction и TransactionSynchronizationRegistry. Между этими двумя интерфейсами контейнер имеет все хуки, которые он должен отслеживать DataSources, EntityManagers и другие ресурсы в текущей транзакции от вашего имени. Эти интерфейсы также позволяют контейнеру предлагать обратные вызовы, такие как SessionSynchronization, а также средства для выполнения других действий от вашего имени после завершения транзакции, такие как сброс / закрытие EntityManager, отправка ожидающих сообщений JMS и сохранение любых таймеров, созданных вашим приложением в курсе. сделки.

Основываясь на спецификации EJB, вы не можете передать контекст транзакции из бина (в данном случае вашего основного класса...) с помощью программной транзакции в другой бин (в данном случае другой) с помощью программной транзакции

Для EJB3 вы обычно определяете распространение транзакции с помощью аннотации @TransactionAttribute.

Атрибут транзакции по умолчанию для всех приложений EJB 3.0 ОБЯЗАТЕЛЬНО:

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

Документы для типа транзакции находятся здесь: http://download.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html

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

Другие вопросы по тегам