2010-12-11 6 views
2

Ich schreibe eine Anwendung für GlassFish 2.1.1 (JavaEE 5, JPA 1.0, soweit ich weiß). Ich habe den folgenden Code in meinem Servlet (was ich meist aus einem Probe auf dem Internet ausgeliehen):EntityManager sieht keine Änderungen in anderen Transaktionen

@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 hat es die folgenden:

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

Das Problem ist, die em doesn‘ t Änderungen sehen, die in einer anderen, externen Transaktion vorgenommen wurden. Grob gesagt, erstelle ich eine Anfrage an mein Servlet vom Webbrowser, sehe Daten, führe etwas DML in der SQL-Konsole durch, lade die Servletseite neu - und es werden keine Änderungen angezeigt. Ich habe versucht, viele Kombinationen von em.flush und utx.rollback und em.joinTransaction zu verwenden, aber es scheint nicht zu tun.

Die Situation ist kompliziert, da ich ein absoluter Neuling in JPA bin, so dass ich kein klares Verständnis davon habe, wie die zugrunde liegenden Maschinen funktionieren. Jede Hilfe und - was noch wichtiger ist - Erklärungen/Links zu dem, was dort passiert, wären sehr willkommen. Vielen Dank!

Antwort

2

Die JPA-Implementierung verwaltet einen Cache von Entitäten, auf die zugegriffen wurde. Wenn Sie Operationen in einer anderen Transaktion ausführen, ohne JPA zu verwenden, ist der Cache nicht mehr auf dem neuesten Stand und Sie sehen daher nie die darin vorgenommenen Änderungen.

Wenn Sie die Änderungen sehen möchten, müssen Sie den Cache aktualisieren. In diesem Fall werden alle Entitäten aus dem Cache entfernt. Natürlich müssen Sie wissen, wann dies zu tun ist (nachdem die andere Transaktion abgeschlossen wurde), sonst werden Sie weiterhin mehrdeutige Entitäten sehen. Wenn dies Ihr Unternehmensbedarf ist, passt JPA möglicherweise nicht zu Ihrer Problemdomäne.

Verwandte:

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

„Wenn Sie Operationen in einer anderen Transaktion durchführen, ohne JPA zu verwenden, ist der Cache nicht mehr up to date“ - es bedeutet, dass Ich hatte JPA benutzt, um Daten in vorher erwähntem Fall zu ändern (und nicht irgendein externes Werkzeug), würde ich Änderungen sehen, nachdem ich Servletseite wiederladen? –

+0

@Andy, ja du würdest. Der EntityManager ist tatsächlich für die Verwaltung des Cache verantwortlich. Sie finden den JPA Concepts Guide unter OpenEJB - http://openejb.apache.org/3.0/jpa-concepts.html als nützlich. –

0

Vielleicht müssen Sie eine Transaktion in der SQL-Konsole durchführen.

1

Wie axtavt sagt, müssen Sie die Transaktion in der Konsole begehen. Angenommen, Sie haben dies getan, ist es auch möglich, dass Daten noch vom PersistenceManager (oder der zugrunde liegenden Infrastruktur) zwischengespeichert werden.

Um Probleme mit dem Caching zu vermeiden, können Sie mit der Hand ausräumen (was schwierig sein kann, da Sie wissen müssen, wann Sie es entfernen müssen), oder Sie können pessimistisch sperren. Pessimistisches Sperren kann die Leistung erheblich beeinträchtigen. Wenn Sie jedoch mehrere unabhängige Verbindungen zur Datenbank haben, haben Sie möglicherweise keine andere Wahl.

Wenn Ihr Prozess die ganze Zeit gleichzeitige Lese-/Schreibzugriffe aus verschiedenen Quellen hat, benötigen Sie möglicherweise pessimistische Sperren. Wenn Sie manchmal eine Stapelaktualisierung von einer externen Quelle haben, können Sie versuchen, aus dieser Stapelverarbeitung Ihre JPA-Anwendung zu signalisieren, die sie entfernen sollte. Vielleicht über einen Webservice oder so. Auf diese Weise würden Sie die gesamte Zeit keine pessimistische Sperrleistungsverschlechterung erleiden.

Die weisee Lektion hier ist, dass die Synchronisation von Prozessen wirklich kompliziert sein kann :)