连接关闭后语句和结果集关闭

时间:2012-07-31 23:53:03

标签: jdbc

我最近搬到了一个项目,我遇到了很多这种性质的代码 - (这是使用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个左右的方法!如果可能的话,我想进一步简化这一点。 感谢您的反馈。

1 个答案:

答案 0 :(得分:0)

finally块中释放连接非常有意义。关闭Statement块中的ResultSetfinally也是如此。

原因很简单:在成功执行和异常情况下,您确保StatementResultSet已关闭。连接也是如此。我会在finally

中做过类似的事情
try{

}catch(Exception exe){

}finally{
    if (stmt != null) stmt.close();
    if (rs != null) rs.close();

    //release connection to connection pool

}

此外,我相信当Statement关闭时,其当前ResultSet也会关闭。因此,如果rsstmt相关联,那么我相信当您执行stmt.close()

时它会被关闭