2010-08-03 4 views
14

J'apprends JPA et le schéma général dans les exemples semble être la suivante:Garder JPA EntityManager ouvert?

EntityManager em = factory.createEntityManager(); 
em.getTransaction().begin(); 
// .... 
em.getTransaction().commit(); 
em.close(); 

Maintenant, je me demande pourquoi nous ne créons sans cesse et EntityManagers proches, plutôt que de le garder ouvert et juste de commencer de nouvelles opérations? Quels sont les avantages et les coûts de le garder ouvert ou de le fermer tout le temps?

Répondre

7

Deux raisons spécifiques JPA viennent à l'esprit:

  1. EntityManager est pas garantie ThreadSafe par la spécification JPA. Par conséquent, les applications JPA portables peuvent uniquement utiliser un EM dans au plus un thread à la fois. L'idiome de création d'une EM locale par méthode et sa fermeture avant qu'elle ne soit hors de portée encourage le confinement de la pile des références EM. Un EM utilisant la durée de vie du contexte de persistance "étendue" conserve un seul contexte de persistance pour toute son existence. Cela signifie que les entités cessent automatiquement de se décoller le commit(). Au lieu de cela, ils doivent être détachés manuellement, sinon les EM restent responsables du suivi.

Cette question est vraiment une version spécifique à JPA de l'ancienne question "quand mettre en pool des objets". C'est une question difficile, mais la réponse est probablement "rarement".

Ce old developerWorks post par expert en concurrence de Java Brian Goetz expose le point. Les gist: pools ont beaucoup de sens pour les objets coûteux, comme les connexions à la base de données. Mais pour les objets de courte durée, petits et à initialisation rapide comme EntityManager, la mise en commun ou toute autre forme de rétention de référence à long terme est difficile à vendre. Mais, c'est une question générale, donc il y a nécessairement des exceptions à cela. Peut-être que l'application est simple ou singlethreaded. Ensuite, ces inquiétudes à propos de la sécurité des threads deviennent discutables.

5

L'ouverture d'un gestionnaire d'entités l'empêche de rétablir sa connexion au pool de connexions.

Ceci peut entraîner plusieurs problèmes, en particulier dans les applications Web, par ex. Lorsque le pool exécute la taille de connexion maximale et maximale, aucun autre utilisateur ne peut obtenir une connexion de base de données empêchant l'accès à la base de données pour cet utilisateur.

Dans ce cas, il est préférable d'avoir des gestionnaires d'entités à courte durée de vie, par ex. ouvrir le gestionnaire d'entités au début d'une requête et le fermer à la fin d'une requête (peut être fait avec des écouteurs/intercepteurs ..). Les entités se détachent alors et vous devez les rattacher si vous voulez les réutiliser (en utilisant l'opération de fusion du gestionnaire d'entités).

Questions connexes