java - MySQL 查询处理花费太长时间并抛出 "Communications link failure"

标签 java mysql jdbc database-connection

我使用 JDBC 连接发出查询:

Connection conn = null
Class.forName("com.mysql.jdbc.Driver")
conn = DriverManager.getConnection(dbHost, dbUser, dbPass)

s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
r = s.executeQuery (MY_SELECT_QUERY);
while(...) { 
  processResultSet(r);
}

while 运行很长时间来处理 ResultSet。大约 1 小时后,我得到了异常:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 74 milliseconds ago. The last packet sent successfully to the server was 4,351,980 milliseconds ago.

   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

   at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
   at com.mysql.jdbc.Util.handleNewInstance(Util.java:407) 
   at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)

   at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3082) 
   at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2968) 
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3516) 
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:931) 
   at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1429) 
   at com.mysql.jdbc.RowDataDynamic.nextRecord(RowDataDynamic.java:416) 
   at com.mysql.jdbc.RowDataDynamic.next(RowDataDynamic.java:395) 
   at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:7171) 
   at com.busk.indexer.AbstractIndexerClient.indexResultSet(AbstractIndexerClient.scala:34)

   at com.busk.indexer.ContinousIndexer.startIndexingLoop(ContinousIndexer.scala:18)

   at com.busk.indexer.IndexerServer$.main(IndexerServer.scala:95) 
   at com.busk.indexer.IndexerServer.main(IndexerServer.scala) 
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

   at java.lang.reflect.Method.invoke(Method.java:597)

我用谷歌搜索了一下,但几乎所有错误都与连接池以及使用连接超过8小时(默认的wait_timeout mysql设置)有关。 就我而言,我正在处理 ResultSet,并收到此错误。

最佳答案

如果发生这种情况是因为结果集中有大量数据,我建议使用“LIMIT s, m”对响应进行分页(其中 s - 起始记录,m - 最大记录 - 均为整数)。然后在循环中一次处理 1000 条记录的部分数据:

boolean finished = false;
int start = 1;
int max = 1000;
do {
   r = s.executeQuery (MY_SELECT_QUERY + " LIMIT " + start + ", " + max);
   finished = // if r returned less than M records
   while(...) { 
     processResultSet(r);
   } 
   start += // number of returned records;
} while (!finished);

当然,1000 是一个任意数字,您可以尝试一下并找到适合您查询的最佳最大大小。

更新:如果每条记录的处理需要很长时间,则将记录存储在列表中,并在从数据库中获取所有数据时迭代它们。

关于java - MySQL 查询处理花费太长时间并抛出 "Communications link failure",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23632593/

相关文章:

java - 为什么 Thread.interrupt() 不能中断试图获取锁的线程

mysql错误操作数应该有1列存储过程

java - 想从 java.sql.ResultSet 扩展

通过 BPXBATCH 的 JDBC - 如何获取 TSO 用户凭证?

java.util.concurrent.ExecutionException : com. google.gson.JsonSyntaxException : 2020-01-15 15:13:42. 0

java - 为什么这些表达式给我输出而不是编译错误?

java - 如何编写公共(public)类 MyList<E>?

mysql - 选择 - MySQL 中按单词排序?

mysql - 尝试使用 MySQL 获取唯一记录

java - 如何使用 JDBC 连接到远程数据库?