使用simplejdbccall时如何在spring中关闭refcursor

时间:2014-05-27 16:56:51

标签: spring oracle jdbc

我使用spring simpleJdbcCall来调用oracle存储过程,我正在使用oracle 11g。

我偶然发现了一些帖子,这些帖子暗示可能存在内存泄漏,因为参考游标没有被弹簧正确关闭。

是否有使用spring simplejdbccall显式关闭光标?或者正在增加oracle OPEN_CURSOR唯一的出路?。

我计划扩展我的应用程序,每小时处理大约一百万笔交易。任何建议都会有所帮助。

2 个答案:

答案 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;
    }