Mysql+JDBC+Linux: executeQuery возвращает пустой набор результатов, когда это не должно

У меня есть следующий код:

public boolean updateDatabase(long houseValue, List<Users> userList)
{
    boolean result = false;
    Connection conn = null;
    PreparedStatement stmtUpdateUsers = null;
    PreparedStatement stmtQueryHouse = null;
    PreparedStatement  stmtUpdateHouse = null;
    ResultSet rs = null;

    String updateUsers = "UPDATE users SET money = ? WHERE username = ?";
    String queryHouse = "SELECT * FROM house WHERE house_id = ?";
    String updateHouse = "UPDATE house SET house_money = ? WHERE house_id = ?";

    try
    {
        conn = getConnectionPool().getConnection();
        conn.setAutoCommit(false);      

        stmtUpdateUsers = conn.prepareStatement(updateUsers);

        ...
        // Here is some code that updates Users table in a short loop
        ...

        stmtQueryHouse = conn.prepareStatement(queryHouse);
        stmtQueryHouse.setInt(1, 1); 
        rs = stmtQueryHouse.executeQuery();
        if(rs.next())
        {
            long houseMoney = rs.getLong("house_money");
            houseMoney += houseValue;

            stmtUpdateHouse = conn.prepareStatement(updateHouse);
            stmtUpdateHouse.setLong(1, houseMoney);
            stmtUpdateHouse.setInt(2, 1); 
            stmtUpdateHouse.executeUpdate();
        }
        else
        {               
            throw new SQLException("Failed to update house: unable to query house table");
        }

        conn.commit();
        result = true;
    }
    catch(SQLException e)
    {           
        logger.warn(getStackTrace(e));
        try{conn.rollback();}catch(SQLException excep)
        {
            logger.warn(getStackTrace(excep));
        }
    }
    finally
    {   
        DbUtils.closeQuietly(rs);
        DbUtils.closeQuietly(stmtQueryHouse);
        DbUtils.closeQuietly(stmtUpdateUsers);
        DbUtils.closeQuietly(stmtUpdateHouse);
        try { conn.setAutoCommit(true); } catch (SQLException e) { /* quiet */ }
        DbUtils.closeQuietly(conn);         
    }

    return result       
}

Этот метод может быть вызван из нескольких потоков, домашняя таблица — это всего лишь таблица с одной строкой, которая содержит общие заработанные деньги. Он обновляется разными потоками.

Проблема в том, что stmtQueryHouse.executeQuery() возвращает пустой набор, и этого не должно происходить, потому что таблица house всегда (с момента создания базы данных) имеет одну строку, которая обновляется (обновляется только столбец house_money).

Когда я запускаю этот код в Windows (драйвер JDBC + mysql 5.5.13), он работает нормально, но когда я запускаю его в CentOS (тот же драйвер JDBC + mysql 5.1.57), он очень часто (если не всегда) возвращает пустой набор результатов. Любая идея, что происходит не так или как я могу проверить, где проблема? Может быть, мне следует использовать select для обновления, но тогда почему он работает в Windows, а не в Linux? Я ценю любую помощь. Заранее спасибо.


person Kovasandra    schedule 12.07.2011    source источник


Ответы (2)


Посмотрите в общем журнале запросов mysql какие-либо ошибки?

Я понимаю, что это не ваш вопрос как таковой, но если у вас есть другая таблица с одной строкой для каждого дома, мне кажется, что было бы более разумно переместить house_money в вашу основную таблицу house

person Cody Caughlan    schedule 12.07.2011
comment
У меня только один дом :) Он просто хранит общие деньги, которые дом зарабатывает со всех игровых комнат. Это что-то вроде скалярного глобального значения. Я думал поместить дом как пользователя в таблицу пользователей, но в конце концов решил отделить его в изолированной таблице с одной строкой из соображений безопасности :) - person Kovasandra; 12.07.2011

Я бы сказал, что этот метод делает слишком много.

Я бы передал Connection трем отдельным методам и управлял транзакцией за пределами всех из них.

Интересно, есть ли оптимизация, которая устранит одно из ОБНОВЛЕНИЙ.

Я хотел бы объединить все это, чтобы не делать обход для каждого пользователя. Он будет работать плохо по мере увеличения числа пользователей.

person duffymo    schedule 12.07.2011
comment
Привет, количество пользователей всегда от 2 до 6. Описанный выше метод обновляет заработок игроков в игровой комнате после каждой завершенной игры. Конечно, игровых комнат может быть много, поэтому мне интересно, есть ли у вас какие-либо идеи, как я могу пакетно обновлять пользовательские обновления? - person Kovasandra; 12.07.2011
comment
Конечно, используйте методы java.sql.Statement addBatch() и executeBatch(): скачать .oracle.com/javase/6/docs/api - person duffymo; 12.07.2011
comment
Большое спасибо, не знал об этом. Это отличная функция :) - person Kovasandra; 12.07.2011