java - 奇怪的 JDBC 执行查询异常

标签 java mysql jdbc large-query

我有以下代码:

 public Object RunQuery(String query) throws Exception{
    System.out.println("Trying to run query");
    Statement stmt = null;
    ResultSet rs = null;
    try {
        stmt = conn.createStatement();
        System.out.println("Got Statement");
        rs = stmt.executeQuery(query);
        System.out.println("Query executed");
        ...


    } catch (SQLException ex) {
        // handle any errors
        System.out.println("SQLException: " + ex.getMessage());
        System.out.println("SQLState: " + ex.getSQLState());
        System.out.println("VendorError: " + ex.getErrorCode());
    }
    catch (Exception ex) {
        System.out.println("Exception: " + ex.getMessage());
    }
    finally {
       if (rs != null) {
            try {
                rs.close();
            } catch (SQLException sqlEx) {
            } // ignore
            rs = null;
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException sqlEx) {
            } // ignore
            stmt = null;
        }
       return ret;
    }
}

运行时效果非常好

query = "SELECT * FROM smalltable"

但是失败了

query = "SELECT * FROM bigtable"

大约有 200K 条记录。 调试器优雅地忽略catch block 并直接进入finally block ;当我将 stmt.executeQuery(query) 添加到监视列表时,NetBeans 给了我这个堆栈框架:

>Exception occurred in target VM: Communications link failure  Last packet sent to the server was 0 ms ago.  
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure  Last packet sent to the server was 0 ms 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:406)

at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)

at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3009)

at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2895)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3438)

at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1951)

at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101)

at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2548)

at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2477)

at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1422)

at RunQuery
Caused by: java.net.SocketException: Software caused connection abort: recv failed

at java.net.SocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.read(SocketInputStream.java:129)

at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:157)

at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:188)

at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2452)

at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2962)

... 9 more




如何在这个框架中进行大型查询?



编辑:我正在使用 J 连接器和 mysql 服务器 5.1;连接字符串是

jdbc:mysql://localhost?user=root&password=password

是的,我知道 select * 是一种不好的做法,但正如你所看到的,我才刚刚开始,这或多或少是我正在进行的第二次测试

最佳答案

我能想到的唯一会导致差异的是某种网络级超时,并且 Netbeans 输出肯定会指向这个方向。您正在使用的 JDBC 连接字符串是什么;也许有一个可以调高的超时参数?

如果问题仍然存在,也可能值得插入网络数据包嗅探器并查看该级别的通信情况。通过短查询和长查询来玩“找不同”游戏,您可能会很好地了解是什么导致一个查询失败而另一个查询成功。

(一般来说,select *是一个坏主意,因为它会带回不必要的所有额外数据。在这种情况下,从大表中的所有行中选择所有列显然会给出与从较小的表中选择相比,连接麻烦。我知道在这种情况下,您的问题仍然有效,因为有时您可能需要这样做,而且除了选择更大的表的子集可能会做同样的事情,但我我只是指出这一点作为一般准则,以防您在生产中使用它作为快捷方式。)

关于java - 奇怪的 JDBC 执行查询异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/465142/

相关文章:

java - hibernate 错误: No Persistence provider for EntityManager named my-unit

java - 从零开始的 Spring MVC 教程

java - 从 Gradle 依赖项中排除 .class 文件

mysql - Kohana框架中得到结果后是否自动关闭数据库连接?

php - 在带有自动加载器的错误处理程序中使用 MySQLi 扩展类

java - 从数据库中检索数据,将数据用作 java 方法的参数

postgresql - jooq 流是异步的吗?

java - 用于呈现未知行数的 JTable

java - 如何从Java中的字符串中提取部分域?

java - JAVA 中如何从 ResultSet 或 ResultSetMetaData 对象中获取数据库表的主键列名?