ORA-01000: 使用 Spring SimpleJDBCCall 时超出最大打开游标数

2023-12-21

我们使用 Spring SimpleJdbcCall 来调用 Oracle 中返回游标的存储过程。看起来 SimpleJdbcCall 没有关闭游标,并且在一段时间后超出了最大打开游标数。

ORA-01000: maximum open cursors exceeded ; nested exception is java.sql.SQLException: ORA-01000: maximum open cursors exceeded spring 

论坛上也有一些人遇到过这种情况,但似乎没有答案。看起来我是 spring/oracle 支持中的一个错误。

这个错误很严重,可能会影响我们未来对 Spring JDBC 的使用。

有没有人遇到过修复方法 - 或者将问题跟踪到 Spring 代码,或者找到避免该问题的解决方法?

我们使用的是 Spring 2.5.6。

这是使用 SimpleJdbcCall 的代码的新版本,它似乎没有正确关闭过程通过游标返回的结果集:

...
SimpleJdbcCall call = new SimpleJdbcCall(dataSource);

Map params = new HashMap();
params.put("remote_user",  session.getAttribute("cas_username") );

Map result = call
  .withSchemaName("urs")
  .withCatalogName("ursWeb")
  .withProcedureName("get_roles")
  .returningResultSet("rolesCur", new au.edu.une.common.util.ParameterizedMapRowMapper() )
  .execute(params);
List roles = (List)result.get("rolesCur")

不使用Spring JDBC的旧版本代码没有这个问题:

oracleConnection = dataSource.getConnection();
callable = oracleConnection.prepareCall(
      "{ call urs.ursweb.get_roles(?, ?) }"    );
callable.setString(1, (String)session.getAttribute("cas_username"));
callable.registerOutParameter (2, oracle.jdbc.OracleTypes.CURSOR);
callable.execute();
ResultSet rset = (ResultSet)callable.getObject(2);
... do stuff with the result set
if (rset != null) rset.close(); // Explicitly close the resultset 
if (callable != null) callable.close(); //Close the callable
if (oracleConnection != null) oracleConnection.close(); //Close the connection

看起来 Spring JDBC 没有调用 rset.close()。如果我在旧代码中注释掉该行,那么在负载测试之后我们会得到相同的数据库异常。


经过多次测试我们已经解决了这个问题。它是我们使用 Spring 框架、Oracle 客户端和 Oracle DB 的组合。我们正在创建新的 SimpleJDBCCalls,它使用 oracle JDBC 客户端的元数据调用,这些调用作为未关闭和清理的游标返回。我认为这是 Spring JDBC 框架中的一个错误,它如何调用元数据但随后不关闭游标。 Spring 应该将元数据从游标中复制出来并正确关闭它。我没有费心用 spring 打开 jira 问题,因为如果您使用最佳实践,则不会表现出错误。

调整 OPEN_CURSORS 或任何其他参数是解决此问题的错误方法,只会延迟它的出现。

我们通过将 SimpleJDBCCall 移动到单例 DAO 中来解决/修复它,这样对于我们调用的每个 Oracle 过程只有一个打开的游标。这些游标在应用程序的整个生命周期内都是打开的 - 我认为这是一个错误。只要 OPEN_CURSORS 大于 SimpleJDBCCall 对象的数量,就不会有麻烦。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ORA-01000: 使用 Spring SimpleJDBCCall 时超出最大打开游标数 的相关文章

随机推荐