注意:我们重复使用单个连接。
************************************************
public Connection connection() {
try {
if ((connection == null) || (connection.isClosed()))
{
if (connection!=null)
log.severe("Connection was closed !");
connection = DriverManager.getConnection(jdbcURL, username, password);
}
} catch (SQLException e) {
log.severe("can't connect: " + e.getMessage());
}
return connection;
}
**************************************************
public IngisObject[] select(String query, String idColumnName, String[] columns) {
Connection con = connection();
Vector<IngisObject> objects = new Vector<IngisObject>();
try {
Statement stmt = con.createStatement();
String sql = query;
ResultSet rs =stmt.executeQuery(sql);//oracle increases cursors count here
while(rs.next()) {
IngisObject o = new IngisObject("New Result");
o.setIdColumnName(idColumnName);
o.setDatabase(this);
for(String column: columns)
o.attrs().put(column, rs.getObject(column));
objects.add(o);
}
rs.close();// oracle don't decrease cursor count here, while it's expected
stmt.close();
}
catch (SQLException ex) {
System.out.println(query);
ex.printStackTrace();
}
最佳答案
init.ora 参数 open_cursors
定义一个 session 可以同时拥有的最大打开游标数。它的默认值为 50。如果应用程序超过此数字,则会引发错误“ORA-01000:超出最大打开游标数”。
因此,当不再需要 JDBC 资源时必须关闭它们,尤其是 java.sql.ResultSet 和 java.sql.Statement。如果它们没有关闭,则应用程序存在资源泄漏。
在重用 Connection 对象的情况下,您必须意识到打开的 oracle 游标将保持打开状态并在连接存在时使用,并且事务尚未结束。当应用程序提交时,打开的游标将被释放。
因此,作为应用程序设计者,您需要粗略估计最复杂的事务所需的打开游标。
困难在于 oracle 的内部参数 View (v$open_cursor、v$sesstat 等)无法显示打开的游标(可重用)和打开的游标(仍被阻塞(不可重用))之间的区别!) 通过未关闭的 ResulSet 或语句。如果您关闭 finally block 中的所有 Statement 和 ResultSet 对象,您的应用程序就完全没问题了。
调整init.ora参数是这样的(我们的应用最多需要800个游标)
ALTER SYSTEM SET open_cursors = 800 SCOPE=BOTH;
关于java - Oracle 在关闭结果集后不删除游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2560350/