在调试时不关闭数据库连接的问题? [英] Problem with not closing db connection while debugging?

查看:77
本文介绍了在调试时不关闭数据库连接的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Java app that opens a connection to a database at the beginning, and closes it at the end. However, the program doesn't always finish, because an exception is thrown or I am debugging it and stop it halfway through.

这会导致开放的连接堆积并减慢数据库的速度,还是会自动清除它?

Will this cause open connections to pile up and slow the database, or will it be cleaned up automatically?

推荐答案

数据库连接由数据库拥有和管理,该类仅使您可以访问该数据库资源.如果不关闭连接,则可能会垃圾收集Java类,但是数据库可能无法判断该连接已不再使用,这可能导致数据库资源被浪费(直到数据库端超时) )甚至泄漏.

A database Connection is owned and managed by the database, the class just gives you access to that database resource. If you don't close the connection then the Java class may be garbage collected, but the database may not be able to tell that the connection is no longer in use which may result in database resources being wasted (until a timeout on the database side) or even leak.

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

So, when you're done with using your Connection, you should be sure to explicitly close it by calling its close() method. This will allow the garbage collector to recollect memory as early as possible and, more important, it releases any other database resources (cursors, handles, etc) the connection may be holding on to.

在Java中,执行此操作的传统方法是在完成对它们的处理后,以finally块的形式关闭ResultSetStatementConnection(按此顺序),并且安全模式看起来像

The traditional way to do this in Java is to close your ResultSet, Statement, and Connection (in that order) in a finally block when you are done with them and the safe pattern looks like that:

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块可以稍作改进(以避免空检查):

The finally block can be slightly improved into (to avoid the null check):

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

但是,这仍然非常冗长,因此您通常最终使用helper类在空安全的helper方法中关闭对象,并且finally块变为类似这样的内容:

But, still, this is extremely verbose so you generally end up using an helper class to close the objects in null-safe helper methods and the finally block becomes something like that:

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

实际上, Apache Commons DbUtils 具有

And, actually, the Apache Commons DbUtils has a DbUtils class which is precisely doing that so there is no need to write your own.

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

In your case, this will solve the problem of the exception, but not the debugging one (and you will waste database resources until the timeout occur on the database side). So 1. don't debug your code using a production database 2. try to execute your debug session until the end.

这篇关于在调试时不关闭数据库连接的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆