我們使用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