Używamy Spring SimpleJdbcCall do wywoływania procedur składowanych w Oracle, które zwracają kursory. Wygląda na to, że SimpleJdbcCall nie zamyka kursorów i po pewnym czasie przekroczone są max otwarte kursory.ORA-01000: maksymalna liczba otwartych kursorów przekroczyła przy użyciu Spring SimpleJDBCCall
ORA-01000: maximum open cursors exceeded ; nested exception is java.sql.SQLException: ORA-01000: maximum open cursors exceeded spring
Jest kilka osób na forach, które doświadczyły tego, ale na pozór nie znalazły odpowiedzi. Wygląda na to, że jestem błędem na wiosnę/oracle support.
Ten błąd jest krytyczny i może mieć wpływ na nasze przyszłe wykorzystanie Spring JDBC.
Czy ktoś napotkał poprawkę - czy śledził problem z kodem źródłowym, czy znalazł obejście, które pozwala uniknąć problemu?
Używamy Spring 2.5.6.
Oto nowa wersja kodu przy użyciu SimpleJdbcCall który wydaje się nie być prawidłowo zamykając wynik ustawić, że powraca proc pośrednictwem kursora:
...
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")
Im starsza wersja kodu, który nie korzysta z wiosna JDBC nie ma tego problemu:
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
wydaje się, że wiosną JDBC nie dzwoni rset.close(). Jeśli skomentuję tę linię w starym kodzie, to po testowaniu obciążenia otrzymamy ten sam wyjątek bazy danych.
Proszę napisać kod pokazujący, w jaki sposób używasz SimpleJdbcCall. Jest bardzo mało prawdopodobne, że jest to błąd na wiosnę i bardziej prawdopodobny sposób, w jaki go używasz, szczególnie biorąc pod uwagę niestandardowy sposób, w jaki Oracle obsługuje zestawy wyników. – skaffman
+1 ze skaffmanem. Jeśli nie możesz znaleźć problemu, spróbuj zbudować solidny testowy test wcześniej, aby zgłosić błąd na stronie http://jira.springframework.org/ –