Bezüglich des Ruhezustandsproblems, auf das meine Kollegen gestern gestoßen sind. Es ist das Grundlegendste am Winterschlaf. Ich verstehe, dass viele Menschen auf dieses Problem gestoßen sind und es sehr häufig vorkommt, aber sie sind oft verwirrt, wenn sie darauf stoßen.
Um den Eindruck zu vertiefen, wissen Sie, was es ist und warum es so ist.
Danach habe ich einfach das ursprüngliche Hibernate-Framework verwendet, um einige Überprüfungen durchzuführen, die SQL-Ausführungskonsole geöffnet und bin zu dem Schluss gekommen:
Die Prämisse ist, dass mitten in derselben Transaktion:
1. Verwenden Sie zum Einfügen die SQL-Anweisung session.createSQLQuery(sql).executeUpdate(); die Ausgabestation druckt dann die SQL-Einfügungsanweisung aus, um session.createSQLQuery(sql).uniqueResult() auszuführen; ; und die SQL-Abfrage wird ebenfalls ausgegeben, es gibt kein Problem und die Daten können abgefragt werden.
2. Verwenden Sie den Ruhezustand, um den Vorgang zu kapseln, und verwenden Sie session.save(entity);, um die eingefügte SQL-Anweisung auszugeben. Es wird auch nicht die SQL-Abfrageanweisung ausgedruckt, aber die Daten können abgefragt werden. Wenn die Transaktions-Commit-Anweisung ausgeführt wird, wird die eingefügte SQL-Anweisung ausgedruckt
3. Verwenden Sie zum Einfügen session.save(entity); und verwenden Sie dann die Anweisung „HQL“ zum Abfragen. Der Effekt ist der gleiche wie im zweiten Punkt oben.
4. Verwenden Sie zum Einfügen session.save(entity); von hibernate, aber die Ausgabekonsole gibt die eingefügte SQL-Anweisung nicht aus. Verwenden Sie dann die SQL-Anweisung, um session.createSQLQuery(sql).uniqueResult(); auszuführen, und die SQL-Abfrageanweisung wird gedruckt. Es ist ein Problem aufgetreten, es konnten keine Daten abgefragt werden. Verwenden Sie in diesem Fall die Methode session.flush(), führen Sie die Methode flush() vor der Abfrage aus und die Ausgabekonsole gibt die eingefügte SQL-Anweisung aus. Wenn Sie erneut abfragen, stehen Ihnen Daten zur Verfügung.
Nachdem die Überprüfung abgeschlossen war, habe ich die obigen Informationen überprüft. Ich glaube, dass viele Menschen darauf gestoßen sind, aber sie sind weiterhin verwirrt. Das hat den Eindruck nur noch vertieft.
Im SQL der Druckkonsole können wir den Ablauf einer einfachen Methode zum Speichern im Ruhezustand sehen:
1. Stellen Sie fest, ob sich die zu speichernde Instanz bereits in einem dauerhaften Zustand befindet. Wenn nicht, platzieren Sie sie im Cache.
2. Planen Sie eine SQL-Einfügeanweisung basierend auf der zu speichernden Instanz. Beachten Sie, dass sie nur geplant und nicht ausgeführt wird.
3. Die zuvor geplante Einfügeanweisung wird ausgeführt, wenn die Transaktion festgeschrieben wird.
Ersetzen Sie tx.commit() durch session.flush. Zu diesem Zeitpunkt gibt das Steuerelement die Einfügeanweisung aus, es werden jedoch keine neuen Datensätze zur Datenbank hinzugefügt.
Die Hauptfunktion der Flush-Methode besteht darin, den Cache zu bereinigen und die Synchronisierung der Datenbank mit dem Hibernate-Cache zu erzwingen, um die Datenkonsistenz sicherzustellen. Seine Hauptaktion besteht darin, eine Reihe von SQL-Anweisungen an die Datenbank zu senden und diese SQL-Anweisungen auszuführen, sie werden jedoch nicht an die Datenbank übermittelt. Die Commit-Methode ruft zuerst die Flush-Methode auf und schreibt dann die Transaktion fest. Aus diesem Grund wird der Datensatz nicht in die Datenbank eingefügt, wenn wir nur Flush aufrufen, da die Aktualisierungen der Datenbank erst gespeichert werden, wenn die Transaktion festgeschrieben wird. Da die Commit-Methode implizit Flush aufruft, rufen wir die Flush-Methode im Allgemeinen nicht explizit auf.
Dies ist der Flush-Mechanismus von Hibernate. Beim Aktualisieren und Speichern einiger komplexer Objekte muss berücksichtigt werden, ob Änderungen in der Reihenfolge der Datenbankoperationen und verzögerte Löschvorgänge Auswirkungen auf die Ergebnisse des Programms haben. Wenn es tatsächlich eine Auswirkung gibt, können Sie Flush hinzufügen, wo Sie die Reihenfolge der Vorgänge beibehalten müssen, um Hibernate zu zwingen, die im Cache aufgezeichneten Vorgänge in die Datenbank zu leeren. Dies sieht vielleicht nicht schön aus, ist aber sehr effektiv.
Frage: Die Methode session.save wird im Cache abgelegt und kann von SQL, das die Datenbank direkt abfragt, nicht ermittelt werden.
Nach der Methode „flush()“ wird das ausgeführte SQL ausgegeben, befindet sich aber noch nicht in der Datenbank. Eine direkte SQL-Abfrage kann die Daten finden.
1. Wo werden die Entitätsdaten nach dem Flush() gespeichert? Der Cache ist derselbe wie die Methode save(), daher sollte SQL ihn nicht abrufen können.
2. Da die Daten nach der Flush-Methode nicht in die Datenbank eingegeben wurden, kann SQL direkt mit session.createSQLQuery(sql) abgefragt werden. Es sollte direkt überprüft werden, ob es sich um die Datenbank handelt, die er abfragt.