0

According to my knowledge, finally block is the best place to close any open resources. (Refer: https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html)

But I am surprised when I have looked at Spring v4.3.5 JdcbTemplate class source. The resources are closed in Catch block of SQLException and finally block, both places. For example:

    //-------------------------------------------------------------------------
// Methods dealing with static SQL (java.sql.Statement)
//-------------------------------------------------------------------------

@Override
public <T> T execute(StatementCallback<T> action) throws DataAccessException {
    Assert.notNull(action, "Callback object must not be null");

    Connection con = DataSourceUtils.getConnection(getDataSource());
    Statement stmt = null;
    try {
        Connection conToUse = con;
        if (this.nativeJdbcExtractor != null &&
                this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
            conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
        }
        stmt = conToUse.createStatement();
        applyStatementSettings(stmt);
        Statement stmtToUse = stmt;
        if (this.nativeJdbcExtractor != null) {
            stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
        }
        T result = action.doInStatement(stmtToUse);
        handleWarnings(stmt);
        return result;
    }
    catch (SQLException ex) {
        // Release Connection early, to avoid potential connection pool deadlock
        // in the case when the exception translator hasn't been initialized yet.
        JdbcUtils.closeStatement(stmt);
        stmt = null;
        DataSourceUtils.releaseConnection(con, getDataSource());
        con = null;
        throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
    }
    finally {
        JdbcUtils.closeStatement(stmt);
        DataSourceUtils.releaseConnection(con, getDataSource());
    }
}

My question is why Spring JDBCTemplate developer put the closing code in both places (SQLException and finally block)?

MFH
  • 357
  • 3
  • 17
  • 1
    The code already has a comment explaining why `// Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet.` – David Florez Jul 07 '17 at 16:01
  • Thanks @DavidFlorez. I also saw the comment. The thing is that it is not clear to me why resources are need to be closed in SQLException block because of ExceptionTranslator? – MFH Jul 07 '17 at 17:18
  • To quote the comment, the _why_: is _"to avoid potential connection pool deadlock"_, for further details, it would probably be better to check if there is a forum (or mailinglist) for Spring development. To be honest, such code would likely only be added if such a deadlock has occurred, or someone has spent enough time to reason that there are edge cases where this could happen. – Mark Rotteveel Jul 08 '17 at 07:32

0 Answers0