web-dev-qa-db-fra.com

JPA - Quand utiliser getTransaction () pour la persistance d'objets

J'ai récemment commencé à travailler avec JPA sur Google App Engine. En lisant quelques exemples, j'ai remarqué quelques variations dans la façon dont les objets sont persistés. Dans un cas, j'ai vu quelque chose comme ça:

entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();

Dans d'autres cas, je ne vois pas l'utilisation de getTransaction (). Je vois simplement entityManager.persist (objet). Quand est-il approprié d'utiliser getTransaction ()?

27
John F.

Si vous utilisez un conteneur géré EntityManager, vous utilisez des transactions JTA. Par conséquent, vous n'avez pas besoin (plus précisément - vous ne pouvez pas) interférer avec les transactions de EntityManager récupérées à l'aide de entityManager.getTransaction(). Le JTA commence et valide votre transaction.

Si vous utilisez une application gérée EntityManager et que vous ne souhaitez pas faire partie d'une transaction JTA, vous devez les gérer vous-même (il s'agit d'un gestionnaire d'entité locale de ressources).

Généralement, l'application EntityManager gérée qui fonctionne avec EntityManager.getTransaction() est utilisée dans l'environnement Java SE.

EDIT: Vous pourriez être intéressé par la section 7.5 Contrôle des transactions de la spécification JPA 2.0 .

19
Piotr Nowicki

Dans GAE, il n’existe pas de Java EE/JTA. Par conséquent, ignorez les termes tels que transaction gérée par le bean (BMT) et transaction gérée par le conteneur (CMT). 

Votre travail est soit transactionnel (où vous souhaitez que plusieurs objets aillent simultanément dans le magasin de données, soit tout doit échouer - c’est là que vous utilisez getTransaction ()), soit non transactionnel (où tout se rend au magasin de données un à un, l'échec d'un persist n'affecte pas les autres - c'est là que vous appelez simplement persist ()/merge ()/remove ()).

5
DataNucleus

Google App Engine a sa gestion des transactions ( https://developers.google.com/appengine/docs/Java/datastore/transactions ), mais l'interface de transaction JPA ne connaît pas certaines des fonctionnalités sous-jacentes de GAE (c'est-à-dire groupes d'entités).

C’est donc à votre application de décider quelles opérations exécuter dans une transaction et lesquelles non. Vous devriez mettre dans une transaction des opérations qui doivent être exécutées de manière atomique.

N'oubliez pas qu'il est recommandé d'effectuer des opérations en cascade et des opérations de relation dans une transaction, car JPA peut déclencher de nombreuses requêtes et entraîner une incohérence dans les données.

Exemple d'utilisation de transaction avec JPA2:

import javax.persistence.EntityTransaction;


EntityTransaction txn = em.getTransaction();
txn.begin();
try {
    //do something with your database
    txn.commit();
} 
finally {
   if (txn.isActive())
      txn.rollback(); 
}
3
andreacipriani

Vous utiliseriez getTransaction() lorsque vous gérez explicitement les transactions dans votre application. D'autre part, si vous laissez le conteneur gérer les transactions pour vous, il ne sera pas nécessaire de commencer/terminer explicitement les transactions. Nous traitons essentiellement de la différence entre Transactions gérées par conteneur (CMT) et Bean Managed Transactions (BMT).

En règle générale, vous utiliseriez BMT lorsque vous avez besoin de davantage de contrôle sur le traitement des transactions ou lorsque des exigences techniques supplémentaires (par exemple, validations en deux phases, transactions distribuées, transactions XA) ne peuvent pas être satisfaites avec CMT. En outre, vous utiliseriez BMT lorsque vos applications sont déployées en dehors d'un serveur d'applications et reposent sur Java SE.

0
Óscar López