В чем разница между @Resource UserTransaction и EntityManager.getTransaction()
может ли кто-нибудь объяснить, в чем разница между:
@Resource
UserTransaction objUserTransaction;
и
EntityManager.getTransaction();
а также что такое управляемая транзакция контейнера? и как это сделать в моем фасаде сеанса, если я хочу вставить три строки в таблицу в транзакции.
3 ответов
EJB являются транзакционными компонентами. Транзакцией может управлять либо сам сервер applicaiton (транзакция, управляемая CMT - контейнером), либо вручную в EJB (транзакция, управляемая BMT - bean).
EJB поддерживает распределенную транзакцию через спецификацию JTA. Распределенная транзакция управляется с помощью UserTransaction
, который имеет методы begin
, commit
, rollback
.
С CMT запускается сервер приложений, фиксация и откат транзакции (согласно заметки транзакции) для вас и вам не позволено вмешиваться. Это означает, что вы не должны получить доступ к UserTransaction
в этом случае. Однако с BMT вы делаете это вручную, и вы сами контролируете транзакцию, используя UserTransaction
.
давайте теперь перейдем к EntityManager
. Реализация JPA может использоваться как на сервере приложений, так и в автономном режиме. Если используется в автономном режиме, необходимо использовать EntityManage.getTransaction
отграничить транзакция JDBC самостоятельно. Если используется на сервере приложений, то EntityManager
сотрудничал с менеджером распределенных транзакций JTA прозрачно для вас.
большую часть времени, вы используете CMT с @Required
аннотация на EJB. Это означает, что вам не нужно получить доступ ни UserTransaction
, ни EntityManager.getTransaction
. Приложение. сервер запускает и фиксирует транзакцию, но также заботится о откате, если возникает исключение. Это то, что я рекомендовал бы для вашего фасад.
(есть больше тонкостей, таких как PersistenceContextType
или ручное зачисление менеджера сущностей в распределенную транзакцию с EntityManager.joinTransaction
, но это только если вы используете технологии по-разному по умолчанию).
UserTransaction
относится к JTA сущность сделки. Вы сможете использовать это только тогда, когда на сервере приложений доступен модуль JTA: например, если вы развертываете приложение с этим на Tomcat (который по умолчанию не поддерживает JTA), код, полагающийся на это, потерпит неудачу. Это тип транзакции по умолчанию, используемый в EJB и MDB.
EntityManager.getTransaction()
получает местные сущность сделки. Это также иногда называют ресурсом локальная транзакция.
локальные транзакции ресурсов сильно отличаются от транзакций JTA: среди прочего, локальные транзакции ресурсов специфичны для ресурса, тогда как транзакции JTA, как правило, специфичны для конкретного потока.
для получения дополнительной информации о разнице между локальными транзакциями ресурсов и транзакциями JTA см. Этот ответ stackoverflow здесь:в чем разница между JTA и локальной транзакцией?
в дополнение к ответу @Marco, который хорошо показывает разницу между локальными транзакциями JTA и ресурсов.
управляемые транзакции контейнера [как он называется] управляются контейнером, а не вашим приложением. Это делается через уровень EJB, где вам просто нужно написать свой метод, и контейнер обернет метод вокруг контекста транзакции, поэтому, если какая-либо часть вашего метода или его вызовы нижнего уровня вызовут исключение, транзакция будет отмена.
его также можно настроить с помощью аннотаций. Более подробную информацию можно найти здесь https://docs.oracle.com/javaee/5/tutorial/doc/bncij.html
обратите внимание, что это делается только через EJBs, а менеджеры сущностей, которые вводятся на веб-уровне( например, сервлеты или REST API), не управляются контейнером, и в этом случае вам нужно искать транзакцию с помощью @Resource UserTransaction
или EntityManager.getTransaction
, begin()
и commit()
себя.
из Java EE 6 Вы разрешено иметь EJBs внутри веб-уровня, поэтому вам не нужно иметь слишком сложный макет проекта, если вы не хотите выставлять EJBs как веб-службы.