Как распространяется UserTransaction? - PullRequest
16 голосов
/ 07 ноября 2010

У меня есть 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 ]

32 голосов
/ 10 ноября 2010

Объект 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 .Между этими двумя интерфейсами контейнер имеет все хуки, необходимые для отслеживания DataSource s, EntityManager s и других ресурсов в текущей транзакции от вашего имени.Эти интерфейсы также позволяют контейнеру предлагать обратные вызовы, такие как SessionSynchronization , а также средства для выполнения других действий от вашего имени после завершения транзакции, такие как сброс / закрытие EntityManager, отправка ожидающих сообщений JMS и сохранение любых созданных таймеров.вашим приложением в ходе транзакции.

4 голосов
/ 08 января 2011

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

0 голосов
/ 10 ноября 2010

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

Требуется атрибут транзакции по умолчанию для всех приложений EJB 3.0:

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

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

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

...