【问题标题】:ExecuteQuery Hangs for unknown reason. Exhausted common solutionsExecuteQuery 因未知原因挂起。用尽了常见的解决方案
【发布时间】:2016-09-08 18:58:24
【问题描述】:

日志停在 logger.warn("Start:preparedStatement.executeQuery()");并无限期挂起。日志中不会抛出异常。该查询未显示在 info 列下的 SHOW FULL PROCESSLIST 中,这意味着该查询甚至没有被执行。我能够在命令行中执行查询,并且只需不到一秒钟的时间就可以恢复所有行。 SHOW OPEN TABLES WHERE IN_USE 0 返回一个空集,因此没有表被锁定。使用 JDK 1.8、MySQL 1.6、InnoDB。 *编辑:这是在 AWS 上运行的,我注意到在挂起之前 CPU 使用率大幅飙升。

public void setup(StringBuilder sql, String[] args, RowMapper<I> rowMapper) throws SQLException{
    this.rowMapper = rowMapper;
    //Create prepared statement
    connection.setAutoCommit(false);
    logger.warn("Start: Connection.preparedStatement");
    preparedStatement = connection.prepareStatement(sql.toString(),ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    logger.warn("End: Connection.preparedStatement");
    preparedStatement.setFetchSize(fetchSize);
    //Setting SQL arguments
    int i = 1;
    for(String var: args){
        preparedStatement.setString(i++, var);
    }
    logger.warn("Start: preparedStatement.executeQuery()");
    resultSet = preparedStatement.executeQuery();
    logger.warn("End: preparedStatement.executeQuery()");
}

【问题讨论】:

  • 因为你的代码看起来不错,我建议你从调试模式开始并冻结所有线程,看看它在哪里。也许这会给你一些方向。
  • 未记录的异常?如果您的日志显示,并且查询没有在 MySQL 端运行,并且“完成”日志没有显示,那么某些东西在这些日志行之间停止了您的线程。线程转储?
  • 在本地调试应用程序是个好主意

标签: java mysql tomcat prepared-statement jdbctemplate


【解决方案1】:

解决了。 StatementImpl.class 版本 1.5 中的第 1373 行附近有一个同步锁,它正在等待锁解除,这就是线程挂起的原因。我同时打开了多个结果集,因此我最终为每个结果集提供了自己的连接,并将获取大小设置为 Integer.MIN_VALUE,并且应用程序现在没有卡住。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-30
    • 2022-12-10
    • 2019-04-30
    • 1970-01-01
    • 2022-01-25
    • 2020-07-17
    • 1970-01-01
    • 2011-05-29
    相关资源
    最近更新 更多