在客户端环境中,我们面临一个Lock on table。 为了重现,我们在我们当地的环境中手动锁定表。
我们需要创建继续执行的块代码,并且在发生此锁定时不会停止。 但是使用SpringJdbc它会停止执行。
这是我正确执行但未停止的代码: 在我们的代码OracleRepositoryJdbcTemplateImpl。
中@Override
public int[] update(final String sql, final BatchPreparedStatementSetter pss,
final String queryName) throws DataAccessException {
long start = executionStart();
try {
return execute(sql, new PreparedStatementCallback<int[]>() {
@Override
public int[] doInPreparedStatement ( final PreparedStatement ps)throws SQLException {
... Code that are correctly executed
logger.warn("********** SQLException");
return int[1];
}
}
);
} finally {
System.out.println("********** Finally of the update method");
queryStop(start, queryName);
}
}
和org.springframework.jdbc.core.JdbcTemplate:
public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
throws DataAccessException {
Assert.notNull(psc, "PreparedStatementCreator must not be null");
Assert.notNull(action, "Callback object must not be null");
if (logger.isDebugEnabled()) {
String sql = getSql(psc);
logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
}
Connection con = DataSourceUtils.getConnection(getDataSource());
PreparedStatement ps = null;
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null &&
this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) {
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
ps = psc.createPreparedStatement(conToUse);
applyStatementSettings(ps);
PreparedStatement psToUse = ps;
if (this.nativeJdbcExtractor != null) {
psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps);
}
T result = action.doInPreparedStatement(psToUse); // HERE
handleWarnings(ps);
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.
if (psc instanceof ParameterDisposer) {
((ParameterDisposer) psc).cleanupParameters();
}
String sql = getSql(psc);
psc = null;
JdbcUtils.closeStatement(ps);
ps = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex);
}
finally {
if (psc instanceof ParameterDisposer) {
((ParameterDisposer) psc).cleanupParameters();
}
JdbcUtils.closeStatement(ps);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
public <T> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
return execute(new SimplePreparedStatementCreator(sql), action);
}
这是在这个评论行中的块执行。 显示日志********** SQLException,但执行永远不会进入我们的finally块。 来自JdbcTemplate的'con'和'ps'对象显示“收集数据......”。
你知道如何解决这个问题吗?
答案 0 :(得分:0)
为了修复它,我们将代码执行嵌套在Callable函数中:
@Override
public int[] update(final String sql, final BatchPreparedStatementSetter pss, final String queryName) throws DataAccessException {
Callable<int[]> call = new Callable<int[]>(){
@Override
public int[] call() throws Exception{
return updateInCallable(sql, pss, queryName)
}
public int[] updateInCallable(final String sql, final BatchPreparedStatementSetter pss, final String queryName) throws DataAccessException {
// Our code
}
}
}