2009-06-18 25 views
0

我們有一個非常簡單的方法,它使用「findById」。Hibernate findById找不到先前找到的記錄

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()); 
    } 
} 

這種方法有時會從快速連續另一個應用程序調用(它基本上是加載了一個購物車的另一個​​系統)。我們有一個線程可以創建購物車,將記錄提交給數據庫,然後應用程序爲每個需要進入數據庫的項目調用一次。雖然其他應用程序按順序發送,並等待響應,但是tomcat在單獨的線程上獲取它們。

我們看到對「getCart」的初始調用實際上能夠找到記錄。偶爾,即使其他通話已經完成,通話也會失敗。這裏的一些日誌提供更多的上下文:

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 

所以。線程20,14成功,但線程10找不到記錄。是什麼賦予了?我們沒有任何緩存(除了默認的第一級緩存)。

<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> 

任何見解,想法或。 。 。好吧,任何事情,都會很感激。

+0

這聽起來像一個會話/事務處理問題,但是你的代碼片段並沒有告訴我們你是如何管理這些資源的。例如,您何時何地提取會話?另外,假設dbSession是一個Hibernate會話對象,那麼Session上就沒有commitTransaction()方法。最後,你是否在任何地方指定了明確的事務隔離? – skaffman 2009-06-19 16:55:09

回答

0

這是由於我們的代碼中的事務錯誤。儘管看起來我們的代碼在每個請求中都啓動了一個新的Session,但偶爾我們發現,這些新的Session並不會獲得新的JDBC連接。我們追查了我們沒有進行交易的地方。由於我們管理調用開始和提交的方式,我們基本上創建了從未完成的長時間運行的事務(並且沒有像預期的那樣)。

0

是否有可能在線程10開始其事務時該ID尚未完全提交事務?所以基本上我問 - 如果你有一個購物車49已經在數據庫中(比如在程序開始時),線程是否仍然有這個問題?

+0

它似乎確實如此,但是有一些線程調用相同的findById和返回對象的相同參數。我相信最初的「插入」是承諾的。但是,如果「更新」未提交(或正在提交),是否可以使其看起來對其他事務不存在事件? – 2009-06-19 17:07:31