Wie kann ich Hibernate konfigurieren, um alle Speicherungen, Aktualisierungen und Löschungen sofort nach der Ausführung der einzelnen Operationen auf den Datenbankserver anzuwenden? Standardmäßig speichert Hibernate alle Speicher-, Aktualisierungs- und Löschvorgänge in der Warteschlange und übergibt sie erst nach einer Operation flush()
an den Datenbankserver, um die Transaktion zu bestätigen oder um die Sitzung zu schließen, in der diese Vorgänge ausgeführt werden.
Ein Vorteil des sofortigen Löschens von Datenbank- "write" -Operationen besteht darin, dass ein Programm alle Datenbankausnahmen abfangen und behandeln kann (z. B. ein ConstraintViolationException ) im Codeblock, in dem sie auftreten. Bei verspätetem oder automatischem Leeren können diese Ausnahmen lange nach der entsprechenden Hibernate-Operation auftreten, die die SQL-Operation verursacht hat.
Aktualisierung:
Laut der Hibernate-API-Dokumentation für die Sitzung ist die Der Vorteil des Abfangens und Behandelns einer Datenbankausnahme vor dem Ende der Sitzung kann von keinerlei Nutzen sein: "Wenn die Sitzung eine Ausnahme auslöst, muss die Transaktion zurückgesetzt und die Sitzung verworfen werden. Der interne Status der Sitzung ist möglicherweise nicht konsistent die Datenbank nach dem Auftreten der Ausnahme. "
Vielleicht besteht der Vorteil des Umschließens einer "unmittelbaren" Hibernate-Session-Schreiboperation mit einem try-catch-Block darin, die Exception zu fangen und zu protokollieren, sobald sie auftritt. Hat das sofortige Spülen dieser Operationen andere Vorteile?
Wie kann ich Hibernate so konfigurieren, dass alle Speicherungen, Aktualisierungen und Löschungen unmittelbar nach der Ausführung der einzelnen Operationen auf den Datenbankserver angewendet werden?
Hibernate bietet meines Wissens keine Möglichkeit dafür. Es sieht jedoch so aus, als ob Spring funktioniert und Sie einige Datenzugriffsoperationen ausführen können FLUSH_EAGER
durch Drehen von %Co_de% bzw. HibernateTemplate
zu diesem Flush-Modus ( Quelle ) .
Aber ich empfehle wärmstens, das Javadoc sorgfältig zu lesen (ich komme darauf zurück).
Standardmäßig speichert Hibernate alle Operationen zum Speichern, Aktualisieren und Löschen in einer Warteschlange und übergibt sie nur nach einer flush () - Operation, dem Festschreiben der Transaktion oder dem Schließen der Sitzung, in der diese Vorgänge ausgeführt werden, an den Datenbankserver.
>
Das Schließen der Sitzung wird nicht durchgeführt.
Ein Vorteil des sofortigen Löschens von Datenbank- "Schreib" -Operationen besteht darin, dass ein Programm alle Datenbankausnahmen (z. B. eine ConstraintViolationException) in dem Codeblock abfangen und behandeln kann, in dem sie auftreten. Bei verspätetem oder automatischem Leeren können diese Ausnahmen lange nach der entsprechenden Hibernate-Operation auftreten, die die SQL-Operation verursacht hat
Zunächst unterscheiden sich die DBMS dahingehend, ob eine Constraint-Verletzung beim Einfügen (oder Aktualisieren) oder beim nachfolgenden Commit zurückkommt (dies wird als sofortige oder verzögerte Constraints bezeichnet). Es gibt also keine Garantie und Ihr DBA möchte vielleicht keine unmittelbaren Einschränkungen (was das Standardverhalten sein sollte).
Zweitens sehe ich persönlich mehr Nachteile mit sofortiger Spülung als Vorteile, wie im Javadoc von HibernateInterceptor
:
Eager Spülen führt zu sofortiger Synchronisation mit der Datenbank, auch wenn in einer Transaktion. Dies bewirkt Inkonsistenzen zu zeigen und zu werfen jeweilige Ausnahme sofort, und JDBC-Zugriffscode, an dem teilnimmt die gleiche Transaktion wird die ändert sich, wie die Datenbank bereits ist sich ihrer dann bewusst zu sein. Aber die Nachteile sind:
- zusätzliche Kommunikations-Roundtrips mit der Datenbank statt einer einzigen Batch bei Transaktion Commit;
- die Tatsache, dass eine tatsächliche Datenbank Rollback benötigt wird, wenn der Ruhezustand Transaktion rollt zurück (wegen bereits gesendete SQL-Anweisungen).
Und glauben Sie mir, dass das Erhöhen der Datenbank-Roundtrips und das Verlieren der Stapelverarbeitung von Anweisungen zu einer
Denken Sie auch daran, dass Sie, sobald Sie eine Ausnahme erhalten, nicht viel mehr tun können, als Ihre Sitzung wegzuwerfen.
Zusammenfassend bin ich sehr glücklich, dass Hibernate die verschiedenen Aktionen in die Warteschlange stellt, und ich würde dieses FLUSH_EAGER
EAGER_FLUSH
sicherlich nicht als allgemeine Einstellung verwenden (aber vielleicht nur für die spezifischen Operationen, die wirklich etwas erfordern, falls überhaupt) ).
Schauen Sie in autocommit
nach, obwohl dies nicht empfohlen wird. Wenn Ihre Arbeit mehr als ein Update enthält oder eine SQL-Anweisung einfügt, Sie einen Teil der Arbeit autocommittieren und eine Anweisung fehlschlägt, haben Sie möglicherweise die schwierige Aufgabe, den ersten Teil der Aktion rückgängig zu machen. Es macht wirklich Spaß, wenn die 'Rückgängig' Operation fehlschlägt.
Wie auch immer, hier ist ein Link, der zeigt, wie man es macht .