2010-12-11 20 views
2

J'écris une application pour GlassFish 2.1.1 (JavaEE 5, JPA 1.0, pour autant que je sache). Je le code suivant dans mon servlet (que je la plupart du temps emprunté à un certain échantillon sur Internet):EntityManager ne voit pas les changements effectués dans d'autres transactions

@PersistenceContext(name = "persistence/em", unitName = "pu") 
private EntityManager em; 

@Resource 
private UserTransaction utx; 

@Override 
protected void doPost(...) { 
    utx.begin(); 
    . . . perform retrieving operations on em . . . 
    utx.rollback(); 
} 

web.xml a ce qui suit dans le:

<persistence-context-ref> 
    <persistence-context-ref-name>persistence/em</persistence-context-ref-name> 
    <persistence-unit-name>pu</persistence-unit-name> 
</persistence-context-ref> 

Le problème est, l'em n » t voir les changements qui ont été faits dans une autre transaction extérieure. En gros, je fais une demande à mon servlet à partir du navigateur Web, voir les données, effectuer une certaine DML dans la console SQL, recharger la page de servlet - et il ne montre aucune modification. J'ai essayé d'utiliser de nombreuses combinaisons de em.flush, et utx.rollback, et em.joinTransaction, mais cela ne semble pas faire du bien.

La situation est compliquée par le fait que je suis un débutant total en JPA, donc je ne comprends pas très bien comment fonctionnent les machines sous-jacentes. Donc toute aide et - plus important encore - les explications/liens de ce qui se passe là-bas seraient très appréciés. Merci!

Répondre

2

L'implémentation JPA conserve un cache des entités auxquelles il a été accédé. Lorsque vous effectuez des opérations dans une transaction différente sans utiliser JPA, le cache n'est plus à jour et, par conséquent, vous ne voyez jamais les modifications apportées.

Si vous souhaitez voir les modifications, vous devrez actualiser le cache, auquel cas toutes les entités seront expulsées du cache. Bien sûr, vous devez savoir quand le faire (une fois l'autre transaction terminée), sinon vous continuerez à voir des entités ambiguës. Si c'est votre besoin d'affaires, alors JPA n'est peut-être pas un bon ajustement à votre domaine de problème.

connexes:

  1. Are entities cached in jpa by default ?
  2. Invalidating JPA EntityManager session
+0

« Lorsque vous effectuez des opérations dans une autre transaction sans utiliser JPA, le cache n'est plus à jour » - Est-ce que cela signifie que J'avais utilisé JPA pour modifier les données dans le cas mentionné ci-dessus (et pas un outil externe), je verrais des changements après avoir rechargé la page de servlet? –

+0

@Andy, oui vous le feriez. L'EntityManager est en effet responsable de la maintenance du cache. Vous pourriez trouver utile le guide des concepts de JPA sur OpenEJB - http://openejb.apache.org/3.0/jpa-concepts.html. –

0

Vous devez peut-être valider une transaction effectuée dans la console SQL.

1

Comme le dit axtavt, vous devez valider la transaction dans la console. En supposant que vous l'ayez fait, il est également possible que les données soient toujours mises en cache par le PersistenceManager (ou l'infrastructure sous-jacente).

Pour éviter les problèmes de mise en cache, vous pouvez les supprimer manuellement (ce qui peut être difficile car vous devez savoir quand les expulser) ou vous pouvez passer au verrouillage pessimiste. Le verrouillage pessimiste peut avoir un impact énorme sur les performances, mais si vous avez plusieurs connexions indépendantes à la base de données, vous n'avez peut-être pas le choix.

Si votre processus a des lectures/écritures simultanées provenant de différentes sources tout le temps, vous aurez peut-être besoin de verrous pessimistes. Si vous avez parfois une mise à jour par lots à partir d'une source externe, vous pouvez essayer de signaler, à partir de ce travail par lots, votre application JPA qu'elle doit expulser. Peut-être via un service web ou alors. De cette façon, vous n'encourez pas de dégradation pessimiste des performances de verrouillage tout le temps.

La sage leçon est ici que la synchronisation des processus peut être vraiment compliqué :)