Estamos utilizando Spring SimpleJdbcCall para llamar a procedimientos almacenados en Oracle que devuelven los cursores. Parece que SimpleJdbcCall no está cerrando los cursores y después de un tiempo se excede el máximo de los cursores abiertos.ORA-01000: se han excedido los cursores máximos cuando se utiliza Spring SimpleJDBCCall
ORA-01000: maximum open cursors exceeded ; nested exception is java.sql.SQLException: ORA-01000: maximum open cursors exceeded spring
Hay algunas otras personas en foros que han experimentado esto, pero al parecer no hay respuestas. Me parece un error en el soporte de Spring/Oracle.
Este error es crítico y podría afectar nuestro uso futuro de Spring JDBC.
¿Alguien ha encontrado una solución, ya sea rastreando el problema hasta el código de Spring o encontró una solución que evita el problema?
Estamos utilizando Spring 2.5.6.
Aquí es la nueva versión del código utilizando SimpleJdbcCall que parece no estar cerrando correctamente el conjunto de resultados que los proc retornos a través de un cursor:
...
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")
La versión anterior del código que no utiliza primavera JDBC no tiene este problema:
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
Al parecer, la primavera JDBC no está llamando rset.close(). Si hago un comentario sobre esa línea en el código anterior, luego de la prueba de carga obtenemos la misma excepción de base de datos.
Por favor, publique un código que muestre cómo está utilizando SimpleJdbcCall. Es muy poco probable que se trate de un error en Spring, y más probablemente de la forma en que lo está utilizando, especialmente si se tiene en cuenta la forma no estándar en que Oracle maneja los resultados. – skaffman
+1 con skaffman. Si no puede encontrar el problema, intente construir un caso de prueba sólido antes de informar un error en http://jira.springframework.org/ –