Wir haben eine sehr einfache Methode, die "findById" verwendet.Hibernate findById findet keine Datensätze, die zuvor gefunden wurden
public Cart getCart(long cartId) {
Cart cart = null;
try {
dbSession.beginTransaction();
cart = (Cart)dbSession.findById(Cart.class, cartId);
dbSession.commitTransaction();
if (logger.isDebugEnabled()) {
logger.debug("The getCart call committed successfully");
}
} finally {
if (dbSession.needsRollback()) {
dbSession.rollbackTransaction();
}
}
logGetCartResults(cartId, cart);
return cart;
}
private void logGetCartResults(long cartId, Cart cart) {
if (logger.isDebugEnabled()) {
StringBuffer message = new StringBuffer("Cart id ");
message.append(cartId)
.append(" was ");
if (cart != null) {
message.append("not ");
}
message.append("null");
logger.debug(message.toString());
}
}
Diese Methode wird manchmal von einer anderen Anwendung in schneller Folge aufgerufen (es ist im Grunde ein anderes System, das einen Wagen lädt). Wir haben einen Thread, der einen Einkaufswagen erstellt, den Datensatz in die Datenbank schreibt und dann die Anwendung einmal für jedes Element aufruft, das in die Datenbank gehen muss. Obwohl die andere Anwendung nacheinander sendet und auf eine Antwort wartet, ruft Tomcat diese auf separaten Threads ab.
Wir sehen erste Anrufe zu "getCart" tatsächlich in der Lage, den Datensatz zu finden. Gelegentlich schlägt ein Anruf fehl, auch nachdem andere Anrufe erfolgreich waren. Hier ist ein Teil des Protokolls, um mehr Kontext zur Verfügung zu stellen:
DEBUG 2009-06-18 16:10:57,145 [http-8080-Processor20] com.eroi.managers.impl.DefaultPurchaseManager: Looking for cartId 49
DEBUG 2009-06-18 16:10:57,146 [http-8080-Processor20] com.eroi.persistors.impl.DefaultPurchasePersistor: The getCart call committed successfully
DEBUG 2009-06-18 16:10:57,146 [http-8080-Processor20] com.eroi.persistors.impl.DefaultPurchasePersistor: Cart id 49 was not null
...
DEBUG 2009-06-18 16:10:57,522 [http-8080-Processor14] com.eroi.managers.impl.DefaultPurchaseManager: Looking for cartId 49
DEBUG 2009-06-18 16:10:57,523 [http-8080-Processor14] com.eroi.persistors.impl.DefaultPurchasePersistor: The getCart call committed successfully
DEBUG 2009-06-18 16:10:57,523 [http-8080-Processor14] com.eroi.persistors.impl.DefaultPurchasePersistor: Cart id 49 was not null
...
DEBUG 2009-06-18 16:10:57,934 [http-8080-Processor10] com.eroi.managers.impl.DefaultPurchaseManager: Looking for cartId 49
DEBUG 2009-06-18 16:10:57,934 [http-8080-Processor10] com.eroi.persistors.impl.DefaultPurchasePersistor: The getCart call committed successfully
DEBUG 2009-06-18 16:10:57,934 [http-8080-Processor10] com.eroi.persistors.impl.DefaultPurchasePersistor: Cart id 49 was null
So. Thread 20, 14 waren erfolgreich, aber Thread 10 konnte den Datensatz nicht finden. Was gibt? Wir haben kein Caching (außer dem standardmäßigen Caching auf der ersten Ebene).
<hibernate-configuration>
<session-factory>
<property name="current_session_context_class">thread</property>
<property name="hibernate.connection.datasource">java:/comp/env/jdbc/ourdb</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
</session-factory>
</hibernate-configuration>
Einsicht, Ideen oder. . . nun, alles ist willkommen.
Das riecht nach einem Session/Transaction-Handling-Problem, aber Ihre Code-Fragmente zeigen uns nicht, wie Sie diese Ressourcen verwalten. Zum Beispiel, wo und wann holen Sie die Sitzung? Wenn dbSession ein Hibernate-Sitzungsobjekt ist, gibt es keine commitTransaction() -Methode für die Sitzung. Schließlich geben Sie eine explizite Transaktionsisolation an beliebiger Stelle an? – skaffman