开发者

Mysql+JDBC+Linux: executeQuery returns empty result set when it shouldn't

开发者 https://www.devze.com 2023-03-20 02:02 出处:网络
I have following code: public boolean updateDatabase(long houseValue, List<Users> userList) { boolean result = false;

I have following code:

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       
}

This method can be called from multiple threads, house table is just a one row table which holds total earned money. It gets updated by different threads.

Problem is that stmtQueryHouse.executeQuery() returns empty set, and it should not happen, because house table always have (since database creation) one single row that gets updated (only house_money column is updated).

When I run this code on windows (JDBC driver + mysql 5.5.13) it works fine, but when I run it on CentOS (same JDBC driver + mysql 5.1.57) it returns empty result set very often (if not always). Any idea what is going wrong or how could I check where is the problem? Maybe I should use select for update, but then why it works on windows and not on linux? I appreciate any help. Thanks in ad开发者_开发知识库vance.


Look in the mysql general query log for any errors?

I realize this isnt your question per se, but if you have another table with just a single row for each House, it sounds to me that it would make more sense to move house_money into your main house table


I'd say this one method is doing far too much.

I'd pass in the Connection to three separate methods and manage the transaction outside all of them.

I'd wonder if there's an optimization that would eliminate one of the UPDATES.

I'd want to batch all these so I didn't do a round trip for each and every user. It'll perform poorly as the # of users increases.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号