gpt4 book ai didi

java - 为什么 "Release Connection"在 jdbcTemplate#execute 的 catch{} block 和 finally{} block 中执行

转载 作者:行者123 更新时间:2023-12-02 02:45:33 25 4
gpt4 key购买 nike

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

Connection con = DataSourceUtils.getConnection(getDataSource());
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null) {
// Extract native JDBC Connection, castable to OracleConnection or the like.
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
else {
// Create close-suppressing Connection proxy, also preparing returned Statements.
conToUse = createConnectionProxy(con);
}
return action.doInConnection(conToUse);
}
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;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
}
finally {
DataSourceUtils.releaseConnection(con, getDataSource());
}
}

最佳答案

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

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

虽然 SQLException 正在被转换,但他们不希望不必要地继续保持连接;因此,他们首先发布它。

请记住,虽然将抛出翻译后的期望,但在向调用者抛出异常之前,finally block 中的代码将运行;但是,finally block 将在这些方法调用之后运行: 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 block 中再次释放连接不会有什么坏处,即使它可能已经在catch block 中释放了。这假设释放已释放的连接或空连接没有任何效果。

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

关于java - 为什么 "Release Connection"在 jdbcTemplate#execute 的 catch{} block 和 finally{} block 中执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44621175/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com