首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇怪的JDBC executeQuery异常

奇怪的JDBC executeQuery异常
EN

Stack Overflow用户
提问于 2009-01-21 12:45:42
回答 3查看 4.6K关注 0票数 0

我有以下代码:

代码语言:javascript
复制
 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;
    }
}

它在运行时运行得非常好。

代码语言:javascript
复制
query = "SELECT * FROM smalltable"

但是失败了

代码语言:javascript
复制
query = "SELECT * FROM bigtable"

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

代码语言:javascript
复制
>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 server 5.1;连接字符串是

代码语言:javascript
复制
jdbc:mysql://localhost?user=root&password=password

是的,我知道select *是一种糟糕的实践,但正如您所看到的,我才刚刚开始,这或多或少是我正在进行的第二个测试

EN

回答 3

Stack Overflow用户

发布于 2009-01-21 12:53:10

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

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

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

票数 1
EN

Stack Overflow用户

发布于 2009-01-21 14:31:28

我马上想到的是,在获取所有这些数据时,可能会出现内存问题。我不知道MySQL是如何设置的,但是您可能想尝试在ResultSet中设置fetch大小,或者通过选择较少的列来限制ResultSet大小。JDBC驱动程序可能试图在一次操作中获取整个表。

顺便说一句,请不要做stmt.executeQuery(查询)。始终使用PreparedStatement并绑定查询参数。在您的示例中没有参数,但这是一种对于安全目的至关重要的实践。切勿将SQL与‘字面值’参数一起使用(例外情况是,字面值是可信的字符串,如代码中的常量或非字符串类型,如已解析的数字)。

票数 1
EN

Stack Overflow用户

发布于 2009-01-28 01:46:38

如果它直接跳到最后,那么在其他代码中抛出的“异常”实际上是错误的后代吗?这将完全避免你的捕获物。

你可能得到了一个OutOfMemoryError,然后得到了网络异常,因为OOME关闭了一些东西?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/465142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档