java - Oracle 在关闭结果集后不删除游标

标签 java oracle jdbc resultset database-cursor

注意:我们重复使用单个连接。

************************************************
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/

相关文章:

java - 从 strings.xml 添加字符串到 ArrayList

sql - PL/SQL 嵌入式插入到可能不存在的表中

java - 数组列表更新到数据库

.net - ODBC Oracle 错误

java - 如何从两个 HTML 表单/子表单向 MySql 数据库插入数据

Java JDBC 公钥连接失败,错误为 : "unable to find valid certification path to requested target"

java cookie操作在firefox中遇到问题?

Java位操作

Java Split 丢弃空数组元素

java - 是否可以将枚举属性的空值存储到数据库中?