Warum gibt iBATIS veraltete Ergebnisse, obwohl das Caching deaktiviert ist?

8

Ich habe eine Webanwendung, die ich langsam mit Spring Data von iBATIS 2 nach JPA migriert habe.

Die meisten Dinge liefen gut, wobei ich nur das DAO für ein Domain-Objekt auf einmal migrierte. Ein Problem, mit dem ich kürzlich konfrontiert wurde, ist jedoch, dass in einigen Teilen der Site veraltete Ergebnislisten angezeigt werden.

Ich habe zum Beispiel einen Abschnitt "ticket", der eine Liste offener Tickets anzeigt und Sie bestimmte Tickets auf separaten Seiten anzeigen lässt. Wenn ich ein neues Ticket erstelle, kann ich dieses Ticket auf seiner spezifischen Seite korrekt anzeigen. Die Liste der offenen Tickets scheint dieses neue Ticket jedoch erst später zu zeigen.

Dinge, die ich ausschließen wollte:

  • Ich sehe dieses Problem sogar auf einem System, auf dem der Abfragecache von MySQL deaktiviert ist
  • Ich sehe dieses Problem, selbst wenn ich cacheModelsEnabled="false" in der iBATIS-Konfiguration eingestellt habe.
  • Ich sehe dieses Problem auch, wenn ich die Attribute <cacheModel> element und cacheModel="x" vollständig aus meiner sqlMap-Datei entferne.
  • Sobald ich die Anwendung neu starte, sehe ich die aktuellen Ergebnisse.
  • Wenn ich die Abfrage ausfühle, sollte iBATIS hier in einem MySQL-Client laufen, ich mache sehe das neue Ticket, das in den Ergebnissen von iBATIS fehlt.
  • Wenn ich eine einfache Ticketliste mit Spring MVC und Spring Data JPA mokierte, sehe ich das neue Ticket.

Ich habe auch versucht, mit iBATIS einen seltsamen Transaktionszustand auszuschließen, aber anscheinend wird hier überhaupt keine Transaktion verwendet.

Was vermisse ich? Gibt es sonst noch etwas, was ich herausfinden sollte? Oder sollte ich die iBATIS-Schicht prioritär vollständig durch Spring Data JPA ersetzen, die vor diesem Problem geschützt zu sein scheint?

AKTUALISIEREN

Ich habe jetzt viele meiner letzten Änderungen mit git bisect durchgespielt, und ich habe es auf eine Änderung eingegrenzt, die Spring's org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter .

Es scheint also, dass eine Transaktion länger dauert, als sie sollte. Ich werde mehr Protokollierung hinzufügen, um zu sehen, ob ich das bestätigen kann, und dann nach einer Möglichkeit suchen, diesen Filter nicht zu verwenden.

    
pioto 31.03.2015, 16:08
quelle

2 Antworten

0

Es scheint also, dass hier eine Kombination von Dingen passiert ist:

  1. Der Großteil meines Codes verwendete nicht explizit Transaktionen.
  2. Ich hatte irgendwann den Tomcat-JDBC-Verbindungspool geändert autocommit wird standardmäßig nicht zurückgesetzt, wenn eine Verbindung zum Pool zurückgegeben wird. Ich erwarte, dass mein älteres DBCP-basiertes Zeug dies jedoch implizit tat.
  3. Die Einführung von OpenEntityManagerInViewFilter kann dazu geführt haben, dass zu einem bestimmten Zeitpunkt ein SET autocommit=0 aufgerufen wurde, mit einem entsprechenden SET autocommit=1 später, wenn sich nichts geändert hat.
  4. Zufällig oder vielleicht ein Design, der Code, der einen neuen Datensatz in die Datenbank einfügte und dann sofort wieder herstellte und zeigte, schien eine andere Connection zu bekommen als der Code, der meine Liste von Datensätzen zeigte.
  5. Die standardmäßige MySQL-Transaktionsisolationsstufe von REPEATABLE-READ bedeutete, dass meine Einträge die alten Ergebnisse enthielten.

Der Fix, den ich gefunden habe, scheint in meinen bisherigen Tests zu funktionieren, indem ich diese defaultAutoCommit und jdbcInterceptors Attribute zu meinem connection pool config hinzufüge:

%Vor%     
pioto 13.05.2015, 21:01
quelle
0

Wenn Sie auswählen, einfügen, wählen Sie in der gleichen SqlSession, dann verursacht der SqlSession-Cache dieses Problem. Du wirst brauchen Löschen Sie den Cache manuell nach dem Einfügen: sqlSession.clearCache ().

    
Naveen Garg 10.04.2015 14:44
quelle

Tags und Links