Hibernate findById не находит записи, которые он ранее нашел - PullRequest
0 голосов
/ 19 июня 2009

У нас есть очень простой метод, который использует "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 не смог найти запись. Что дает? У нас нет никакого кэширования (кроме кэширования 1-го уровня по умолчанию).

<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 голосов
/ 24 июня 2009

Это произошло из-за ошибки транзакции в нашем коде. Даже при том, что казалось, что наш код запускает новую Сессию в каждом запросе, мы обнаружили, что время от времени эти новые Сессии не получат новое соединение JDBC. Мы отследили, где мы не совершали транзакцию. Из-за того, как мы управляем вызовами, чтобы начать и зафиксировать, мы по существу создавали длительную транзакцию, которая никогда не завершалась (и не вела себя как ожидалось).

0 голосов
/ 19 июня 2009

Возможно ли, что в то время, когда поток 10 начинает свою транзакцию, ID еще не является полностью зафиксированной транзакцией? Итак, в основном я спрашиваю - если у вас есть корзина 49 уже в базе данных (скажем, в начале программы) может ли поток все еще иметь эту проблему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...