为什么"发布连接"在catch {}块中执行,在finally {}块中执行jdbcTemplate #execute

时间:2017-06-19 01:40:01

标签: java jdbc

.top-h1

1 个答案:

答案 0 :(得分:2)

根据catch (SQLException ex)块中的注释,编写此代码的人考虑到以下行可能需要一些时间来运行其初始调用:

throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);

当SQLException被翻译时,他们不希望连接仍然被不必要地保留;因此,他们首先发布它。

请记住,虽然会抛出已翻译的期望,但finally块中的代码将在向调用者抛出异常之前运行;但是,finally块将在这些方法调用之后运行:getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex)

另一种方法是使用以下等效代码:

catch (SQLException ex) {
    // Release Connection early, to avoid potential connection pool deadlock
    // in the case when the exception translator hasn't been initialized yet.
    DataSourceUtils.releaseConnection(con, getDataSource());
    con = null;

    // create the translated exception
    Exception et = getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);

    // throw the translated exception
    throw et;
}
finally {
     // release the connection.
     // If a SQLException is caught above, then this will run before 
     // the translated exception is thrown to the caller
     DataSourceUtils.releaseConnection(con, getDataSource());
}

此外,他们认为尝试在finally块中再次释放连接也没有什么坏处,即使它已经在catch块中释放了。这假设释放已释放或空连接无效。

值得注意的是,无论在try块中抛出SQLException,您仍然希望尝试释放连接。因此,需要在finally块中这样做。