Hibernate -Query -Cache - für Objekte, die nicht im Cache der 2. Ebene - riskant? nützlich? Schlechte Praxis?

StackOverflow https://stackoverflow.com/questions/1998326

Frage

Im Zusammenhang damit Frage

Prämisse:

Dies sind meine Annahmen, basierend auf meiner Lektüre, Erfahrung und meinem Verständnis, sie können falsch sein, wenn sie es sind, bitte kommentieren und ich werde die Frage bearbeiten.

  • Abfrage -Cache ist hauptsächlich gut zusammen mit dem 2. Level -Cache
  • Abfragen zwischengeschnittenen Cache Die Identifikatorenergebnisse von Abfragen + Parametern
  • Abfrage -Cache ist riskant, wenn die Datenbank geändert wurde, und sie war nicht im Cache reflektiert

Frage:

Ich habe ein Objekt, das sich nicht im Cache der 2. Ebene befindet. Aufgrund einiger schlechter Programmierungen oder anderer Einschränkungen wird der Code, der das Objekt lädt, mehrere Zeit in derselben Hibernate -Sitzung aufgerufen. Das Retival verwendet eine HQL -Abfrage, z.

 hibernateTemplate.find("from Foo f where f.bar > ?", bar);

Vor dem Hinzufügen von Abfragebachel

Dann wollte ich sehen, was passiert, wenn ich Abfragemestriche hinzufüge:

 Query query = session.createQuery("from Foo f where f.bar > ?");
 query.setCacheable(true);
 query.setParameter(bar);
 query.list();

Als ich einen Abfrage -Cache hinzufügte, habe ich bemerkt, dass Hibernate während derselben Sitzung die Datenbank n -mal nicht mehr, nur einmal pro Sitzung.

  1. Meine erste Annahme ist also, dass der Winterschlaf zuerst im Sitzungscache sucht, dann im 2. Level -Cache. Ist diese Annahme richtig?
  2. Ich gehe auch davon aus, dass wenn das Objekt (Foo) Das ist nicht im Cache der 2. Ebene, wurde in der Datenbank geändert, dann wird der Cache abfragen, der Cross -Session Scoped, die falschen Kennungen und damit die falschen Objekte zurückgibt. Ist das korrekt?
  3. Ist es dann sicher zu sagen, dass es eine gute Praxis ist, auch für nicht 2L -Objekte mit Abfragemittel für Abfragen unveränderliche Informationen zu verwenden? (z. B. eine Abfrage, dass die Klausel eine Bedingung enthält, die immer die gleichen Ergebnisse zurückgibt, z. "

Übrigens im verwandten Frage Es wird behauptet, dass Abfrage -Cache nicht auf dem Sitzungs -Cache -Bereich funktioniert. Verstehe ich diese Behauptung oder etwas anderes?

War es hilfreich?

Lösung

Ein Abfrage -Cache ist ein bestimmter Typ von Cache auf 2. Ebene. Was Sie als Cache der 2. Ebene bezeichnen, würde ich lieber "Objekt -Cache" aufrufen.

Kommentare zu Ihren Annahmen:

  • Abfrage -Cache ist hauptsächlich gut zusammen mit Cache auf 2. Ebene (auch bekannt als Objektcache).

Ein Abfrage -Cache enthält nur die rohen Ergebnisse der Abfragen als Primärschlüssel, in Hibernate Speak, IDs. Es hält die tatsächlichen hydratisierten Objekte nicht. Dies ist sinnvoll, als wenn Sie eine Abfrage mit JDBC ausführen, gibt es Ihnen nur zurück, was mit hydratisierten (besiedelten) Objekten nach dem Ergebnis wiederhergestellt ist. Die Aussage ist nicht unbedingt korrekt. Wenn die Abfrage sehr kompliziert ist und somit eine sehr lange Ausführung dauert, speichern Sie diese Zeit, indem Sie einen Abfrage -Cache verwenden. Durch die Verwendung eines Abfragestells speichern Sie nicht die Zeit zum Laden der Objekte aus der Datenbank.

  • Abfrage -Cache ist riskant, wenn die Datenbank geändert wurde, und sie war nicht im Cache reflektiert

Dies gilt, aber es ist nicht einzigartig für Abfrages -Cache, dasselbe gilt für das, was Sie als 2nd -Level -Cache bezeichnen, aber das, was normalerweise als Objektcache bezeichnet wird.

Meine erste Annahme ist also, dass der Winterschlaf zuerst im Sitzungscache sucht, dann im 2. Level -Cache. Ist diese Annahme richtig?

Ja, beim Laden von Objekten ist dies das Verhalten.

Ich gehe auch davon aus, dass, wenn das Objekt (FOO), das sich nicht im Cache der 2. Ebene befindet, in der Datenbank geändert wurde, und den Cache, der Cross -Session Scoped ist, die falschen Kennungen und damit die falschen Objekte zurückgibt. Ist das korrekt?

Ja, sowohl der Objekt -Cache als auch der Abfrage -Cache werden betroffen. Dies ist nur besorgniserregend, wenn die Datenbank geändert wird, ohne über Hibernate zu gehen. Sie können den Effekt möglicherweise mildern, indem Sie die Zeitüberschreitung des Abfrage -Cache festlegen.

Ist es dann sicher zu sagen, dass es eine gute Praxis ist, auch für nicht 2L -Objekte mit Abfragemittel für Abfragen unveränderliche Informationen zu verwenden? (z. B. eine Abfrage, dass die Klausel eine Bedingung enthält, die immer die gleichen Ergebnisse zurückgibt, z. "

Für diese Art von Objekten gibt es keinen Grund, nicht sowohl einen Objekt -Cache als auch einen Abfragemanien -Cache zu verwenden.

Und ja, Abfrage -Cache funktioniert nicht auf Sitzungsstufe, auch als Cache von Level 1, Level 1. Der Grund, warum, wenn Sie die Abfrage erneut ausführen, die Datenbank erneut trifft. Es wird das Ergebnis (ID -Set) einer Abfrage nicht in den Sitzungscache eingerichtet.

Andere Tipps

Nur Annahmen:

Demzufolge Artikel Aus Hibernate -Dokumentation:

Query -Cache] erstellt zwei neue Cache -Regionen: eine Holding -Abfrageergebnisse (org.hibernate.cache.standardQuerycache), die anderen Zeitstempel der neuesten Aktualisierungen für abfragen zu erfassen (org.hibernate.cache.updatetimestampscache).

Ich gehe davon aus, dass dies bedeutet, dass wenn der Zeitstempel der abfragbaren Tabelle neuer als die Ergebniseinstellung ist - es bewirkt, dass der Winterschlaf der DB im nächsten Aufruf für diese Abfrage nähert, und das, was den Abfrage -Cache in gewisser Hinsicht sicher macht.

Aber 2 Sätze später in demselben Absatz der Dokumentation heißt es:

Der Abfrage-Cache sollte immer in Verbindung mit dem Cache der zweiten Ebene verwendet werden.

Ich gehe davon aus, dass dies der einzige Weg ist, wie Winterschlaf von Änderungen an der Datenbank, die aus der Sitzung dieses bestimmten Benutzers ausgeführt werden, bewusst sein kann

Für Ihre Frage Nr. 3 glaube ich nicht, dass Sie den Abfrage -Cache verwenden möchten, wenn die Objekte nicht zwischengespeichert werden. Am Ende haben Sie alle primären IDs, müssen jedoch einmal pro Schlüssel die Datenbank drücken, um die Objekte abzurufen, die möglicherweise langsamer sind als die Abfrage ohne Caching auszuführen. Ab 3,3 sowieso greift es in neueren Versionen vielleicht die fehlenden Objekte mit weniger Abfragen ab, z. B. wo id in (: id1,:: id2, ...).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top