虽然数据在DB中,但MySQL Select返回一个空的ResultSet?不同的联系会得到不同的结果

时间:2016-10-17 09:26:43

标签: java mysql spring-jdbc

我们有两个应用服务器与同一个DB通信。一个是TCP服务器,另一个是HTTP服务器(我们希望用新的HTTP服务器替换旧的TCP服务器......但是需要它们一起工作一段时间。)

两台服务器都以相同的方式与DB通信。 Spring-JDBC具有完全相同的代码。

在测试环境中运行此设置时,一切正常,但在云服务器上进行生产部署时,会出现一种非常奇怪的现象。

似乎(只是一个猜测,我可能完全错误)数据库连接以某种方式"阻止"或者"锁定"来自 特定行 的彼此。虽然没有一个MySQL查询使用锁。

例如,此查询会发生什么:HTTP服务器上的SELECT * FROM users WHERE uid = '?'为?= x返回一个空的ResultSet,当从TCP服务器运行x时,相同的完全查询返回正确的行。该行确实在数据库中,不应返回空。

在两台服务器上运行此查询的代码如下:

public UserDBO getUserRecord(String uid) throws SQLException {
    UserDBO result = null;
    try {
        JdbcOperations jdbcOperations = new JdbcTemplate(dataSource);
        String query = "SELECT *" + " FROM " + TABLE_USERS + " WHERE " + COL_UID + "=" + quote(uid);
        logger.config("Executing SQL query:[" + query + "]");
        result = jdbcOperations.queryForObject(query, new UserDboRowMapper());
    } catch(EmptyResultDataAccessException ignored) {}
    return result;
}

两个服务器DAO都使用相同的用户帐户连接到数据库。检查服务器配置表明它不应该是一个问题(每个帐户最大并发连接数和所有其他相关配置不受限制)。

我们知道问题不在代码中,因为如上所述它在测试环境中完美运行。所以我们认为它必须是数据库服务器配置。 但它有什么用呢?

我知道这个问题的特殊性,但我很绝望,别无选择,只能向StackOverFlow社区寻求帮助。

提前致谢。

更新1

添加quote()方法代码:

private String quote(String str) {
    return "\"" + str + "\"";
}

更新2

重要的是要澄清,一旦我关闭HTTP服务器,重新启动服务器计算机并启动只有TCP服务器它可以正常对MySQL DB。

这导致我们相信这里有一些阻塞/锁定机制,因为似乎服务器以某种方式打断了彼此对数据库的访问,即使它们使用相同的DAO代码与之通信。

另外,为了澄清,所有组件(TCP,HTTP和DB)都在同一台机器上。

更新3

添加UserDBO目标代码:

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class UserDBO {

private String uid;
private String token;
private Date registered_date;
private UserStatus userStatus;
private Date unregistered_date;
private int unregistered_count;
private String deviceModel;
private String androidVersion;
}

UserDboRowMapper代码:

public class UserDboRowMapper implements org.springframework.jdbc.core.RowMapper<UserDBO> {
@Override
public UserDBO mapRow(ResultSet resultSet, int i) throws SQLException {
    return new UserDBO(resultSet.getString(COL_UID),
                        resultSet.getString(COL_TOKEN),
                        resultSet.getDate(COL_REGISTERED_DATE),
                        UserStatus.valueOf(resultSet.getString(COL_USER_STATUS)),
                        resultSet.getDate(COL_UNREGISTERED_DATE),
                        resultSet.getInt(COL_UNREGISTERED_COUNT),
                        resultSet.getString(COL_DEVICE_MODEL),
                        resultSet.getString(COL_ANDROID_VERSION));
}

}

0 个答案:

没有答案