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:
cacheModelsEnabled="false"
in der iBATIS-Konfiguration eingestellt habe. <cacheModel>
element und cacheModel="x"
vollständig aus meiner sqlMap-Datei entferne. 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.
Es scheint also, dass hier eine Kombination von Dingen passiert ist:
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. 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. Connection
zu bekommen als der Code, der meine Liste von Datensätzen zeigte. 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:
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 ().