调试时没有关闭数据库连接的问题?

时间:2010-01-23 02:17:35

标签: java jdbc

我有一个Java应用程序,它在开始时打开与数据库的连接,并在最后关闭它。但是,程序并不总是完成,因为抛出异常或者我正在调试它并在中途停止它。

这会导致打开连接以堆积和减慢数据库速度,还是会自动清理?

4 个答案:

答案 0 :(得分:8)

数据库连接由数据库拥有和管理,该类只允许您访问该数据库资源。如果不关闭连接,那么Java类可能被垃圾收集,但数据库可能无法告知连接不再使用,这可能导致数据库资源被浪费(直到数据库端超时) )甚至泄漏。

因此,当您完成使用Connection后,您应确定通过调用其close()方法明确关闭它。这将允许垃圾收集器尽早重新收集内存,并且更重要,它会释放连接可能保留的任何其他数据库资源(游标,句柄等)。

在Java中执行此操作的传统方法是在完成后在ResultSet块中关闭StatementConnectionfinally(按此顺序)与他们和安全模式看起来像这样:

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
    // Do stuff
    ...

} catch (SQLException ex) {
    // Exception handling stuff
    ...
} finally {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (ps != null) {
        try {
            ps.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) { /* ignored */}
    }
}

可以稍微改进finally块(以避免空检查):

} finally {
    try { rs.close(); } catch (Exception e) { /* ignored */ }
    try { ps.close(); } catch (Exception e) { /* ignored */ }
    try { conn.close(); } catch (Exception e) { /* ignored */ }
}

但是,这仍然是非常冗长,所以你通常最终使用一个帮助器类来关闭null安全帮助器方法中的对象,finally块变成这样:

} finally {
    DbUtil.closeQuietly(rs);
    DbUtil.closeQuietly(ps);
    DbUtil.closeQuietly(conn);
}

实际上,Apache Commons DbUtils有一个DbUtils类正是这样做的,所以不需要自己编写。

在您的情况下,这将解决异常问题,但不会解决调试问题(并且您将浪费数据库资源,直到数据库端发生超时)。所以1.不要使用生产数据库调试代码2.尝试执行调试会话直到结束。

答案 1 :(得分:2)

这是Sun(错误...... Oracle?)says

建议程序员明确关闭不再需要的连接和语句。

程序员用Java编程语言编写代码而不使用任何外部资源不需要担心内存管理。垃圾收集器在不再使用时自动删除对象并释放它们正在使用的内存。当内存不足时,它将回收丢弃的对象,使它们当前占用的内存可用于快速重用。

但是,如果应用程序使用外部资源,就像它使用JDBC API访问DBMS时一样,垃圾收集器无法知道这些资源的状态。它仍将回收丢弃的对象,但如果Java堆中有大量可用内存,即使(少量)Java垃圾持有大量昂贵的数据库资源,它也可能不经常收集垃圾。因此,建议程序员在不再需要时立即关闭所有连接(使用方法Connection.close)和语句(使用方法Statement.close),从而尽可能早地释放DBMS资源。这尤其适用于因不同DBMS而异,因为从一个DBMS到另一个DBMS的变化。

我会将数据库访问放在try块中,并确保关闭finally块中的所有语句和连接。

答案 2 :(得分:2)

您的数据库服务器将具有超时设置。它将关闭连接并回滚任何未提交的事务。对于任何具有生产能力的数据库产品,这种情况已经发生了数十年。

如果你想正确使用试试{..你的代码..}最后{..close connections ..}

答案 3 :(得分:0)

不。

如果你的程序继续并且你的连接还活着,那么BD就会拒绝你的判决。

如果您的连接发生了某些事情(例如,超时),那么BD就是谁关闭了该连接并且它没有消耗资源。

如果您释放了连接,并且调用了垃圾收集器(可能需要一段时间),连接将在释放之前自行关闭。

如果您的程序在没有关闭连接的情况下终止,则所有(操作系统)进程将释放其本机资源,以及它们之间连接到BD的本机资源(可能是网络套接字)。然后,BD将接收中止/关闭连接并释放您的连接。

唯一可能发生的事情是,只有一次执行会多次连接到BD并做一些非常糟糕的事情让它们保持打开状态,从而阻碍所有可用的连接。但我认为这不是你的情况。

修改:一般来说,BD是 bad-client-behavior -proof