Statement and Resultset close after connection clo

2019-08-29 01:34发布

问题:

I have recently moved to a project where I am encountering a lot of code of this nature - (This is using the jdbc postgres driver)

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();
}

Apparently this code has been in production for a while, without causing issues.

What I find hard to understand is, in the exception flow, the connection gets closed or returned to the pool first; and then the statement and resultset are attempted to be closed. Does it make sense to execute this after the parent connection object is closed ?

Because of the way the code is structured, connection release has to be done in the exception block. That cannot be changed. That being said, is it okay to leave the stmt.close() and rs.close() in finally after the connection has been released to the pool ?

To clarify further, if my understanding is correct (i.e., statement and resultset must be closed before connection close and not after), I need to repeat some code between the catch and finally. The revised code now looks as below. Can this be simplified ?

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);
      }
  }

Just for perspective, this code is all over - at least a 100 or so methods ! I would like to simplify this further if possible. Appreciate your feedback.

回答1:

It makes perfect sense for connections to be released in the finally block. And so does closing your Statement and ResultSet in your finally block.

The reasoning is simple: You're making sure that your Statement and ResultSet gets closed, in both successful execution and exception scenario. The same goes for connection. I would've done something like this in the finally block

try{

}catch(Exception exe){

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

    //release connection to connection pool

}

Also, I believe that when a Statement is closed, its current ResultSet is also closed. So in case rs is associated with stmt, then I believe it would be closed when you execute stmt.close()



标签: jdbc