0

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

4

1 回答 1

0

finally在块中释放连接是非常有意义的。关闭你的StatementResultSet在你的finally街区也是如此。

原因很简单:在成功执行和异常情况下,您都确保您的Statementand被关闭。ResultSet连接也是如此。finally我会在街区做这样的事情

try{

}catch(Exception exe){

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

    //release connection to connection pool

}

另外,我相信当 aStatement关闭时,它的电流ResultSet也关闭了。因此,如果rs与 相关联stmt,那么我相信它会在您执行时关闭stmt.close()

于 2012-08-01T02:48:44.337 回答