我最近搬到了一个项目,我遇到了很多这种性质的代码 - (这是使用jdbc postgres驱动程序)
try {
Connection conn = pool.getAConnection(); //home-grown conn pool
PreparedStatement ps = ..;
ResultSet rs = ..;
rs = ps.executeQuery();
...
} catch (SQLException se) {
conn.close();
} finally {
if (stmt != null) stmt.close();
if (rs != null) rs.close();
}
显然这段代码已经生产了一段时间,没有引起问题。
我发现难以理解的是,在异常流程中,连接首先被关闭或返回到池中;然后尝试关闭语句和结果集。父连接对象关闭后执行此操作是否有意义?
由于代码的结构方式,必须在异常块中完成连接释放。这无法改变。 话虽如此,在连接释放到池后,最终是否可以将stmt.close()和rs.close()保留在最后?
进一步澄清,如果我的理解是正确的(即语句和结果集必须在连接关闭之前关闭而不是之后关闭),我需要在catch和finally之间重复一些代码。修订后的代码现在如下所示。这可以简化吗?
try {
...
} catch(Exception ex){
if (rs != null) {
close(rs); rs = null; // close() method impl just calls rs.close() in try-catch block
}
if (ps != null) {
close(ps); ps = null;
}
processException( ex, con); // This method logs and then either closes the connection or releases to pool, depending on some conditions.
con = null;
} finally {
if (rs != null) {
close(rs);
}
if (ps != null) {
close(ps);
}
if (null != con) {
close(con);
}
}
仅仅是为了透视,这段代码全部结束 - 至少100个左右的方法!如果可能的话,我想进一步简化这一点。 感谢您的反馈。
答案 0 :(得分:0)
在finally
块中释放连接非常有意义。关闭Statement
块中的ResultSet
和finally
也是如此。
原因很简单:在成功执行和异常情况下,您确保Statement
和ResultSet
已关闭。连接也是如此。我会在finally
块
try{
}catch(Exception exe){
}finally{
if (stmt != null) stmt.close();
if (rs != null) rs.close();
//release connection to connection pool
}
此外,我相信当Statement
关闭时,其当前ResultSet
也会关闭。因此,如果rs
与stmt
相关联,那么我相信当您执行stmt.close()