我有一个Java应用程序,它在开始时打开到数据库的连接,并在结束时关闭它。然而,程序并不总是结束,因为抛出了一个异常,或者我正在调试它并在中途停止了它。
这会导致打开的连接堆积并减慢数据库速度,还是会自动清除?
发布于 2010-01-23 11:34:43
数据库连接由数据库拥有和管理,类只提供对该数据库资源的访问。如果不关闭连接,那么Java类可能会被垃圾收集,但数据库可能无法判断连接不再使用,这可能会导致数据库资源浪费(直到数据库端超时),甚至泄漏。
因此,当您使用完Connection时,您应该确保通过调用它的close()方法显式地关闭它。这将允许垃圾收集器尽可能早地重新收集内存,更重要的是,它将释放连接可能持有的任何其他数据库资源(游标、句柄等)。()
在Java语言中这样做的传统方法是,当您使用完ResultSet、Statement和Connection (按此顺序)时,将它们关闭在finally块中,安全模式如下所示:
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块稍微改进为(以避免null检查):
} finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { ps.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}但是,这仍然是非常冗长的,所以你通常会使用一个帮助器类来关闭空安全的帮助器方法中的对象,finally块变成了这样:
} finally {
DbUtil.closeQuietly(rs);
DbUtil.closeQuietly(ps);
DbUtil.closeQuietly(conn);
}实际上,Apache Commons DbUtils有一个DbUtils类,它就是这样做的,所以不需要编写自己的类。
在您的情况下,这将解决异常问题,但不会解决调试问题(并且您将浪费数据库资源,直到数据库端发生超时)。所以1.不要使用生产数据库调试你的代码2.试着执行你的调试会话直到最后。
发布于 2010-01-23 10:38:49
以下是Sun (err...Oracle?) says的内容
建议程序员在不再需要时显式关闭他们创建的连接和语句。使用Java编程语言编写代码并且不使用任何外部资源的程序员不需要担心内存管理。当不再使用对象时,垃圾回收器会自动删除这些对象,并释放它们正在使用的内存。当内存不足时,它将回收丢弃的对象,使它们当前占用的内存可用于快速重用。但是,如果应用程序使用外部资源,就像它使用JDBC API访问DBMS时一样,垃圾收集器无法知道这些资源的状态。它仍然会回收被丢弃的对象,但如果Java堆中有大量空闲内存,它可能不会频繁地进行垃圾收集,即使(少量) Java垃圾占用了大量昂贵的数据库资源。因此,建议程序员在不再需要时立即显式关闭所有连接(使用方法Connection.close)和语句(使用方法Statement.close),从而尽早释放DBMS资源。这尤其适用于需要使用不同DBMS的应用程序,因为不同的DBMS之间存在差异。
我会将数据库访问放在try块中,并确保关闭finally块中的所有语句和连接。
发布于 2010-01-23 10:42:20
您的数据库服务器将具有超时设置。它将关闭连接并回滚任何未提交的事务。在任何具有生产能力的数据库产品上,这种情况已经发生了几十年。
如果您想要正确地执行此操作,请尝试{ ..your代码..}最后使用{ ..close连接..}
https://stackoverflow.com/questions/2121805
复制相似问题