在我们的Web应用程序中,我们经常遇到此问题
ORA-01000 maximum open cursors exceeded
我知道这与代码没有正确关闭游标(ResultSet
,PreparedStatement
等)有关。
示例:
public List<Employee> getAllEmployees() throws DatabaseException{
Connection conn = DatabaseHelper.getConnection(); //Get a connection from the connection pool
PreparedStatement pst = null;
ResultSet rs = null;
List<Employee> emps = new ArrayList<Employee>();
try {
pst = conn.prepareStatement("SELECT * FROM EMPLOYEE ORDER BY EMP_ID");
rs = pst.executeQuery();
while(rs.next()) {
//Do something
}
} catch (SQLException e) {
logger.error("ERROR getting all employees", e);
throw new DatabaseException("Could not get all employees due to an internal error", e);
} finally {
try { pst.close(); } catch(Exception ignore) {} //Close the prepared statement
try { rs.close(); } catch(Exception ignore) {} //Close the Resultset
try { conn.close(); } catch(Exception ignore) {} ////Close the connection, thus returning it to the pool
}
return emps;
}
尽管我知道我正在关闭游标和finally
块中的连接,但我不了解的是我如何才能实际验证游标在Oracle数据库中是否已关闭?
我当前正在运行以下查询(假设我的数据库用户名是EMP
)
select * from v$open_cursor where sid in (select sid from v$session where username='EMP' and program ='JDBC Thin Client');
这为我提供了通过JDBC瘦客户端连接的会话的打开游标的行列表。但是,即使在调用pst.close()
,rs.close()
和conn.close()
之后,查询仍会返回相同的行,这似乎表明游标仍处于打开状态。
我使用JProfiler检查泄漏。但是,它告诉我是否要关闭Connection
对象,但不会告诉我PreparedStatement
,Statement
和ResultSet
我已经参考了以下帖子,并且已经按照说明进行了操作,但是它们似乎都没有回答我的问题,即如何验证Oracle中是否关闭了游标(使用SQL Developer或其他方法)工具)?
答案 0 :(得分:0)
首先也是最重要的一点,v$open_cursor
不是当前打开的游标列表。为此,我认为您需要v$sesstat
和v$statname
的某种组合,但我不确定。
您的open_cursors
参数设置为什么?我认为默认值为50,但是Oracle建议将其至少设置为500。