Nous utilisons Spring SimpleJdbcCall pour appeler des procédures stockées dans Oracle qui renvoient des curseurs. Il semble que SimpleJdbcCall ne ferme pas les curseurs et après un certain temps, les curseurs max ouverts sont dépassés.ORA-01000: Curseurs ouverts maximum dépassés lors de l'utilisation de Spring SimpleJDBCCall
ORA-01000: maximum open cursors exceeded ; nested exception is java.sql.SQLException: ORA-01000: maximum open cursors exceeded spring
Il y a quelques autres personnes sur les forums qui ont expérimenté cela mais apparemment pas de réponses. Cela me ressemble comme un bug dans le support du printemps/oracle.
Ce bug est critique et pourrait avoir un impact sur notre utilisation future de Spring JDBC.
Est-ce que quelqu'un a rencontré un correctif - soit en dépistant le problème au code de ressort ou a trouvé une solution de contournement qui évite le problème?
Nous utilisons Spring 2.5.6.
Voici la nouvelle version du code à l'aide SimpleJdbcCall qui semble ne pas être fermer correctement le jeu de résultats que les rendements proc via un curseur:
...
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")
L'ancienne version du code qui n'utilise pas Spring JDBC n'a pas ce problème:
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
Il semblerait que le printemps JDBC ne demande pas rset.close(). Si je commente cette ligne dans l'ancien code, après le test de chargement, nous obtenons la même exception de base de données.
Veuillez poster un code indiquant comment vous utilisez SimpleJdbcCall. Il est extrêmement improbable qu'il s'agisse d'un bug au printemps, et plus probablement de la manière dont vous l'utilisez, en particulier si l'on considère la manière non standard qu'Oracle gère les jeux de résultats. – skaffman
+1 avec skaffman. Si vous ne pouvez pas trouver le problème, essayez de construire un cas de test solide avant de signaler un bug à http://jira.springframework.org/ –