Как распространяется 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. Между этими двумя интерфейсами контейнер имеет все хуки, которые он должен отслеживать DataSource
s, EntityManager
s и другие ресурсы в текущей транзакции от вашего имени. Эти интерфейсы также позволяют контейнеру предлагать обратные вызовы, такие как SessionSynchronization, а также средства для выполнения других действий от вашего имени после завершения транзакции, такие как сброс / закрытие EntityManager, отправка ожидающих сообщений JMS и сохранение любых таймеров, созданных вашим приложением в курсе. сделки.
Основываясь на спецификации EJB, вы не можете передать контекст транзакции из бина (в данном случае вашего основного класса...) с помощью программной транзакции в другой бин (в данном случае другой) с помощью программной транзакции
Для EJB3 вы обычно определяете распространение транзакции с помощью аннотации @TransactionAttribute.
Атрибут транзакции по умолчанию для всех приложений EJB 3.0 ОБЯЗАТЕЛЬНО:
Если клиент вызывает метод корпоративного компонента, в то время как клиент связан с контекстом транзакции, контейнер вызывает метод корпоративного компонента в контексте транзакции клиента.
Документы для типа транзакции находятся здесь: http://download.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html
NB. Постоянство контекста и распространение транзакций обычно происходят вместе, но не всегда - будьте осторожны. Например, сессионные компоненты с состоянием могут иметь расширенный контекст постоянства.