我正在审查一大堆现有代码,试图找到会导致连接池耗尽或抛出其他错误的未关闭连接。
在某些地方,我看到连接被返回到池中,ResultSet已关闭,但PreparedStatement未关闭。
在伪代码中它看起来像这样:
Connection conn = null;
try {
conn = MyJdbcTemplateHolder.getNewConnectionFromPool();
PreparedStatement ps = conn.prepareStatement(sql, ...);
ResultSet rs = st.executeQuery();
// do stuff with results
} catch(Exception e) {
// exception
} finally {
rs.close();
MyJdbcTemplateHolder.returnConnectionToPool(conn);
//***** Here is what's missing: st.close(); *****
}
问题是: open语句是否会导致问题,因为它没有显式关闭?或者是关闭ResultSet并返回足够的连接?
显然,我不是在谈论一个公开声明 - 我们在代码中有100个连接池和数十个可能出现此问题的地方。
答案 0 :(得分:2)
答案是是的,可能会导致问题。正如SO中所讨论的那样:
如果你在完成它们之后没有以相反的顺序关闭与连接相关的资源(或者在finally块中),那么你将面临风险。连接池的处理方式各不相同,但令人担忧的是 - 最低限度 - 将一组不正确的资源重新放回池中。
如果不清楚(你可能已经知道这一点),这里将进一步讨论如何正确关闭资源:
请注意,在即将推出的Java 7中,这里会有一些帮助:
http://www.javaspecialists.eu/archive/Issue190.html
其中在Java中引入了一个新的try-with-resources语句,该语句自动关闭try语句中引用的任何AutoCloseable资源。