Hibernate findById找不到以前找到的记录

时间:2009-06-18 23:48:13

标签: mysql hibernate tomcat

我们有一个使用“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>

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

2 个答案:

答案 0 :(得分:0)

当线程10开始其事务时,ID可能还不是完全提交的事务吗?所以基本上我问 - 如果你已经在数据库中有一个购物车49(比如在程序的开头),那么线程是否还有这个问题?

答案 1 :(得分:0)

这是由于我们的代码中存在交易错误。尽管看起来我们的代码在每个请求中都启动了一个新的Session,但我们发现,偶尔这些新的Session将不会获得新的JDBC连接。我们追踪了我们没有进行交易的地方。由于我们管理开始和提交调用的方式,我们基本上创建了从未完成的长期运行事务(并且没有按预期运行)。