我们使用Spring SimpleJdbcCall调用Oracle中返回游标的存储过程。它看起来像SimpleJdbcCall没有关闭游标,并在一段时间后超过了最大打开游标。ORA-01000:使用Spring时超出最大打开游标SimpleJDBCCall
ORA-01000: maximum open cursors exceeded ; nested exception is java.sql.SQLException: ORA-01000: maximum open cursors exceeded spring
还有一些人在论坛上经历过这个但看似没有答案的人。它看起来像是spring/oracle支持中的一个bug。
这个bug很重要,可能会影响我们将来使用Spring JDBC。
是否有人遇到过修复 - 要么将问题跟踪到Spring代码,要么找到避免问题的解决方法?
我们使用Spring 2.5.6。
下面是使用SimpleJdbcCall时这似乎无法正确关闭结果集通过游标PROC返回代码的新版本:
...
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()。如果我在旧代码中注释掉那行,那么在加载测试后,我们会得到相同的数据库异常。
请张贴一些代码,显示您如何使用SimpleJdbcCall。这很可能不是Spring中的错误,更可能是您使用它的方式,特别是考虑到Oracle处理结果集的非标准方式。 – skaffman 2009-09-17 08:55:32
+1与skaffman。如果你找不到问题,可以尝试构建一个坚如磐石的测试用例,以在http://jira.springframework.org/上报告错误。 – 2009-09-17 15:02:27