В чем разница между @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 как веб-службы.