Ich schreibe eine webbasierte Anwendung mit Hibernate und Jsp / Servlet. Ich habe über die Methoden sessionFactory.getCurrentSession
und sessionFactory.openSession
gelesen. Ich kenne den grundlegenden Unterschied zwischen ihnen (mit getCurrentSession
müssen Sie die Verbindung nicht schließen, und wenn Sie die Transaktion festschreiben, wird Ihre Sitzung automatisch geschlossen). Nach meinem Verständnis sollten wir uns für getCurrentSession
entscheiden und dies über Session-pro-Request tun.
Betrachten wir das folgende Szenario:
getCurrentSession
auf und erhält die aktuelle Sitzung getCurrentSession
hat und eine Transaktion Jetzt sind meine Fragen
Wird die in Schritt 1 und Schritt 3 gefundene Sitzung dieselbe Sitzung sein?
Sie sollten identisch sein, das ist irgendwie Teil des Vertrags von getCurrentSession()
und Sie erhalten die Session
an den Thread gebunden, solange die Arbeitseinheit nicht abgeschlossen wurde (dh eine Transaktion wurde festgeschrieben) oder zurückgerollt). Java Persistence with Hibernate setzt es so (S.481):
Der gesamte Datenzugriffscode, der
getCurrentSession()
für die globale Freigabe aufruftSessionFactory
erhält Zugriff auf die gleiche aktuelleSession
- wenn es in der aufgerufen wird Gleicher Thread. Die Arbeitseinheit ist abgeschlossen, wennTransaction
festgeschrieben (oder zurückgesetzt) wurde. Hibernate spült auch und schließt den aktuellenSession
und seinen Persistenzkontext, wenn Sie die Transaktion festschreiben oder zurücksetzen. Die Implikation ist hier, dass ein Aufruf vongetCurrentSession()
nach dem Commit oder Rollback einen neuenSession
und einen frischen Persistenzkontext erzeugt.
Und Sie möchten vielleicht auch lesen, was das Javadoc von ist Session#beginTransaction()
sagt.
Wenn die Antwort für die Frage 1 ja ist, wie würde sie das Commit in Schritt 4 behandeln? Im Idealfall sollte sie die Sitzung dort selbst schließen und in Schritt 5 einen Fehler geben.
Schritt 4 sollte kein Problem sein, der Session
wird geleert, der Transaction
wird übernommen und der Session
wird geschlossen. Aber ich erwarte, dass Schritt 5 mit einer TransactionException
fehlschlägt meine Wette). Aber lassen Sie mich das Javadoc von Transaction
zitieren:
Wie oben betont, diskutieren wir etwas, was nicht passieren sollte (d. h. ein Designproblem).Eine Transaktion ist einer Sitzung zugeordnet und wird normalerweise durch einen Aufruf von
Session.beginTransaction()
instanziiert. Eine einzelne Sitzung kann sich über mehrere Transaktionen erstrecken, da der Begriff einer Sitzung (eine Konversation zwischen der Anwendung und dem Datenspeicher) gröber ist als der Begriff einer Transaktion. Es ist jedoch vorgesehen, dass zu jeder Zeit höchstens eine nicht festgeschriebene Transaktion mit einer bestimmten Sitzung verknüpft ist .
Ich habe keine Antwort für Ihr Szenario, weil ich es nicht so implementieren würde, da es nach Problemen zu fragen scheint. Stattdessen würde ich die Transaktion in C starten, wo C A und B aufruft und C das Commit ausgibt. Skeletal:
%Vor% Also, a()
und b()
committen oder rollback nicht - woher wissen sie, dass die gesamte Geschäftsaufgabe abgeschlossen wurde? Sie könnten eine Ausnahme auslösen oder einen booleschen Wert zurückgeben, um dem Aufrufer mitzuteilen, dass etwas nicht in Ordnung ist und ein Rollback erforderlich ist.