我使用spring simpleJdbcCall来调用oracle存储过程,我正在使用oracle 11g。
我偶然发现了一些帖子,这些帖子暗示可能存在内存泄漏,因为参考游标没有被弹簧正确关闭。
是否有使用spring simplejdbccall显式关闭光标?或者正在增加oracle OPEN_CURSOR唯一的出路?。
我计划扩展我的应用程序,每小时处理大约一百万笔交易。任何建议都会有所帮助。
答案 0 :(得分:1)
实际上Spring JDBC没有这样的问题。执行完毕后,它会关闭finally
内的所有资源。 SimpleJdbcCall
使用JdbcTemplate
:
public <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action)
throws DataAccessException {
try {
...
}
catch (SQLException ex) {
...
}
finally {
if (csc instanceof ParameterDisposer) {
((ParameterDisposer) csc).cleanupParameters();
}
JdbcUtils.closeStatement(cs);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
ResultSet
OUT参数相同:
protected Map<String, Object> processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param) throws SQLException {
....
finally {
JdbcUtils.closeResultSet(rs);
}
return returnedResults;
}
从另一方面来说,我在高负载系统中对Spring JDBC和Oracle有着丰富的经验,并希望说我们在峰值负载时注意到Oracle上有足够的开放资源,但之后它们已经正确发布。
虽然我们使用了JBOSS池DataSource
及其TransactionMaanger
答案 1 :(得分:0)
我直接使用CallableStatement,可以快速安全地释放语句和连接,可以尝试这两种方法并测量内存消耗,它非常适合解决内存消耗和连接保留问题,这些问题证明了应用程序的许多等待和拒绝连接。
try {
log.info("**** RepositoryPSostgres.getAllProducts ******** ");
Connection conn = jdbcTemplate.getDataSource().getConnection();
conn.setAutoCommit(false);
// Procedure call.
CallableStatement proc = conn.prepareCall("{? = call get_all_products() }");
proc.registerOutParameter(1, Types.OTHER);
proc.execute();
ResultSet results = (ResultSet) proc.getObject(1);
**proc.close();
proc.isClosed();
conn.close();**
ArrayList <Products> resp = new ArrayList <Products>();
while (results.next()) {
Products resp1 = new Products();
resp1.setId(results.getInt("id"));
resp1.setName((String) results.getString("name"));
resp1.setPrice((BigDecimal) results.getBigDecimal("price"));
resp.add(resp1);
log.info("***" + results.getInt("id") + "***** ");
log.info("***" + results.getString("name") + "***** ");
log.info("***" + results.getBigDecimal("price") + "***** ");
}
results.close();
return resp;
} catch (Exception e) {
e.printStackTrace();
log.error(new StringBuffer("Error en transaccion en saldo CashPooling : ").append(e.getLocalizedMessage()).toString());
return null;
}