web-dev-qa-db-fra.com

Quelle est la différence entre @Resource UserTransaction et EntityManager.getTransaction ()

Quelqu'un peut-il expliquer quelle est la différence entre:

@Resource
UserTransaction objUserTransaction;

et

EntityManager.getTransaction();

Et aussi qu'est-ce qu'une transaction gérée par conteneur? et comment dois-je le faire dans ma façade de session si je veux insérer trois lignes dans un tableau en transaction.

29
TCM

Les EJB sont des composants transactionnels. La transaction peut être gérée soit par le serveur d’application lui-même (CMT - transaction gérée par conteneur), soit manuellement par vous-même au sein de l’EJB (BMT - transaction gérée par un bean).

EJB prend en charge les transactions distribuées via la spécification JTA. La transaction distribuée est contrôlée à l'aide de UserTransaction , qui a les méthodes begin, commit, rollback.

Avec CMT, le serveur d’application démarre, valide et annule la transaction (conformément aux annotations de transaction ) pour vous et vous n’êtes pas autorisé à intervenir. Cela signifie que vous ne devez pas accéder à UserTransaction dans ce cas. Cependant, avec BMT, vous le faites manuellement et vous contrôlez la transaction vous-même à l'aide de la variable UserTransaction.

Passons maintenant à la EntityManager. Une implémentation JPA peut être utilisée dans un serveur d'applications ou de manière autonome. Si vous l'utilisez de manière autonome, vous devez utiliser EntityManage.getTransaction pour démarquer vous-même la transaction JDBC. Si elle était utilisée dans un serveur d'applications, la EntityManager coopérait de manière transparente avec le gestionnaire de transactions distribuées JTA. 

La plupart du temps, vous utilisez CMT avec l'annotation @Required sur l'EJB. Cela signifie que vous n'avez besoin d'accéder ni à UserTransaction ni à EntityManager.getTransaction. L'application. Le serveur démarre et valide la transaction, mais prend également soin de revenir en arrière si une exception est déclenchée. C'est ce que je recommanderais pour votre façade.

(Il y a plus de subtilités, telles que PersistenceContextType ou l'inscription manuelle du gestionnaire d'entités dans une transaction distribuée avec EntityManager.joinTransaction , mais ce n'est que si vous utilisez les technologies de manière différente, comme le défaut).

27
ewernli

UserTransaction fait référence à l'entitéJTAtransaction. Vous ne pourrez l'utiliser que lorsqu'un module JTA est disponible sur le serveur d'applications: par exemple, si vous déployez une application avec cela sur Tomcat (qui, par défaut, ne prend pas en charge JTA), le code utilisant cette méthode échouera. . Il s'agit du type de transaction par défaut utilisé dans les EJB et les MDB. 

EntityManager.getTransaction() récupère une entité local transaction. Cette opération est parfois appelée transaction locale de ressources. 

Les transactions locales de ressources sont très différentes des transactions JTA: entre autres choses, les transactions locales de ressources sont spécifiques à une ressource, alors que les transactions JTA ont tendance à être spécifiques à un thread particulier. 

Pour plus d'informations sur la différence entre les transactions de ressources locales et JTA, reportez-vous à la réponse ci-dessous: Quelle est la différence entre une transaction JTA et une transaction locale?

8
Marco

En plus de la réponse de @ Marco qui fait bien la différence entre les transactions JTA et de ressources locales.

Les transactions gérées par conteneur sont [comme il est nommé] gérées par le conteneur plutôt que par votre application. Cela se fait par le biais du niveau EJB où il vous suffit d'écrire votre méthode et le conteneur encapsulera la méthode autour d'un contexte de transaction. Ainsi, si une partie de votre méthode ou ses appels de niveau inférieur lève une exception, la transaction sera annulée.

Il peut également être ajusté à l'aide d'annotations. Plus d'informations peuvent être trouvées ici https://docs.Oracle.com/javaee/5/tutorial/doc/bncij.html

Notez que cela se fait uniquement via des EJB et que les gestionnaires d'entités injectés sur le niveau Web (par exemple, les servlets ou l'API REST ne sont pas gérés par le conteneur. Dans ce cas, vous devez rechercher la transaction à l'aide de @Resource UserTransaction ou EntityManager.getTransaction, begin() et commit() vous-même.

À partir de Java EE 6, vous pouvez utiliser des EJB dans la couche Web. Vous n'avez donc pas besoin d'une structure de projet trop complexe, à moins que vous ne vouliez commencer à exposer vos EJB en tant que services Web.

0
Archimedes Trajano