【问题标题】:java.sql.SQLException: ORA-01000: maximum open cursors exceeded while truncating tablesjava.sql.SQLException: ORA-01000: 截断表时超出最大打开游标
【发布时间】:2013-07-29 01:49:59
【问题描述】:

我在截断模式中的所有表时遇到此异常。
我在我的 Java 代码中截断了 3 个模式,第一种方法从给定的模式名称中获取表名列表,第二种方法执行 "TRUNCATE TABLE table_name" 查询。
我对我的代码在截断第一个和第三个模式时总是成功感到困惑。但是在第二个模式上执行时,我得到 ORA-01000 错误。
我的截断代码是

    private void truncateTable(Connection conn, String tableName) {
    PreparedStatement ps = null;
    try {
        ps = conn.prepareStatement(Utility.TRUNCATE_TABLE + tableName);
        ps.executeUpdate();
    } catch (SQLException e) {
        log.error("SQLException occured while getting table names from schema", e);
    } finally {
        Utility.free(ps, null, null);
    }
}


    private List<String> getAllTableNames(Connection conn) {
    PreparedStatement ps = null;
    ResultSet rs = null;
    List<String> list = new ArrayList<String>();
    try {
        ps = conn.prepareStatement(Utility.SELECT_ALL_TABLE_NAMES);
        rs = ps.executeQuery();
        while (rs.next()) {
            list.add(rs.getString("TABLE_NAME"));
        }
    } catch (SQLException e) {
        log.error("SQLException occured while getting table names from schema", e);
    } finally {
        Utility.free(ps, rs, null);
    }
    return list;
}

    public static void free(PreparedStatement ps, ResultSet rs, Connection conn) {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {
            log.error("Error occurred while closing ResultSet",e);
        }
    }
    if (ps != null) {
        try {
            ps.close();
        } catch (SQLException e) {
            log.error("Error occurred while closing PreparedStatement",e);
        }
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) {
            log.error("Error occurred while closing Connection",e);
        }
    }
}

代码有什么问题,或者是 Oracle 中的模式配置有什么问题? 我该如何解决这个问题?

【问题讨论】:

  • 确保在获取表名时关闭所有这些结果集。
  • 是的,确定我添加了我的代码,并且在异常成功截断其他其他模式的表之后

标签: java oracle


【解决方案1】:

如果您要遍历 getAllTableNames 生成的 List 并在紧密循环中调用 truncateTable,则您在 finally 块中的 free 调用可能会被延迟并堆积到一定程度t 为下一次迭代清除足够快 - 因为您只知道 finally 将在某个时候被调用,而不一定是在控制权返回给调用者之前立即调用。

架构大小会对此产生影响,因此小型架构成功而大型架构失败可能是有意义的。如果发生了这种情况,那么您应该在tryfinally 中调用free

    private void truncateTable(Connection conn, String tableName) {
    PreparedStatement ps = null;
    try {
        ps = conn.prepareStatement(Utility.TRUNCATE_TABLE + tableName);
        ps.executeUpdate();
        Utility.free(ps, null, null);
        ps = null;
    } catch (SQLException e) {
        log.error("SQLException occured while getting table names from schema", e);
    } finally {
        if (ps != null) {
            Utility.free(ps, null, null);
        }
    }
}

如果Utility.free 检查ps 是否为空,那么在finally 块中的检查可能是多余的,但没有它,如果没有SQLExceptionfree 将被调用两次。

【讨论】:

  • 是的,Alex 我遍历 List 和 Utility.free 方法检查 ps 是否不为 null 它关闭 ps inside 方法。
  • 架构许多表中出现错误。超过 50 个表,但其他成功的模式每个都有 10 个表。也许它会导致错误。
  • @Ugur - 将free 移动到try 中可以解决问题吗?如果您在该调用中正确释放,则架构大小应该不再相关。正如另一个想法,即使rs 为空,free 是否真的释放了ps
  • 不幸的是它不起作用。我认为这是关于模式的。因为我总是得到相同的错误和相同的架构。
  • @Ugur - 我只能认为free 没有按预期工作;也许您可以将该方法的代码添加到问题中(not 作为评论)?
【解决方案2】:

检查代码并确保在使用后关闭游标。如果问题仍然存在,请将 OPEN_CURSORS 设置为更多值。

【讨论】:

  • 那么请将打开的游标设置为更多值,暂时会对您有所帮助
猜你喜欢
  • 2015-03-29
  • 2012-08-24
相关资源
最近更新 更多