Oracleでは、カーソルを戻すストアド・プロシージャをコールするためにSpring SimpleJdbcCallを使用しています。 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 JDBCの使用に影響する可能性があります。
問題をSpringコードにトラッキングするか、問題を回避する回避策を見つけた人がいますか?
私たちはSpring 2.5.6を使用しています。
...
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")
コードの古いバージョンを使用しない:ここでは
は正しくカーソル経由のprocリターンが結果セットを閉じることがないように見えるSimpleJdbcCallを使用してコードの新しいバージョンです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
+1 with skaffman。問題が見つからない場合は、http://jira.springframework.org/でバグを報告する前に、堅実なテストケースを構築してみてください。 –