【问题标题】:ORA-00604, ORA-01000 errors in C# with Oracle; max open cursors exceededORA-00604,Oracle 的 C# 中出现 ORA-01000 错误;超出最大打开游标
【发布时间】:2017-08-20 16:59:15
【问题描述】:

大家好:我有一个程序运行 4 个与 Oracle 数据库对话的线程。我在每个线程都有本地的 Oracle 连接,并且我正在使用 USING 语句以及手动关闭记录集并关闭连接。据我了解,当打开的记录集多于数据库上配置的游标时,会出现 ORA-01000 错误。我不明白为什么我的记录集保持打开状态或为什么会出现此错误。代码如下:

    static void CheckPaths()
    {
        int pathcount = paths.Count; //paths is a typed list           
        Parallel.ForEach(paths, new ParallelOptions { MaxDegreeOfParallelism = 4 }, (p) =>
        {
            try
            {
                CheckSinglePathAllHours(p);
            }
            catch (Exception ex)
            {
                //there is logging here, this is where the exception hits
            }
        });
    }

    static void CheckSinglePathAllHours(Path p)
    {
        string sqlBase = @"Select * from table ";//this is actually a big SQL statement
        using (DBManager localdbm = new DBManager())
        {
                string sql = sqlBase;             
                OracleDataReader reader = localdbm.GetData(sql);
                while (reader.Read())
                {
                       //process the path, query always returns 24 or less rows
                }
                reader.Close();
                reader = null; //is this even necessary?               
                localdbm.Close(); //is this necessary in conjunction with the USING statement?
        }
    }

class DBManager : IDisposable
{
    OracleConnection conn;
    OracleCommand cmd;
    public DBManager()
    {
        string connStr = "blah blah blah";            
        conn = new OracleConnection(connStr);
        conn.Open();
        cmd = conn.CreateCommand();
    }
    public OracleDataReader GetData(string sql)
    {
        cmd.CommandText = sql;
        cmd.CommandTimeout = 900;
        return cmd.ExecuteReader();
    }
    public void RunSQL(string sql)
    {
        cmd.CommandText = sql;
        cmd.CommandTimeout = 900;
        cmd.ExecuteNonQuery();
    }
    public void Close()
    {
        conn.Close();
    }
    public void Dispose()
    {
        try
        {
            conn.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

代码通常会在异常发生前运行大约一两分钟。异常消息有两个:ORA-00604:递归 SQL 级别 1 发生错误;和 ORA-01000:超出最大打开游标。任何想法我做错了什么?

【问题讨论】:

  • OracleDataReaderOracleConnection 实现 IDisposable,但您不会在任何地方处理它们。处置 != 关闭。
  • 考虑使用 odp.net 和连接池。更多信息请参见here
  • Paul,看起来像在阅读器上调用 .Dispose() 并且连接解决了问题。

标签: c# oracle oracle11g


【解决方案1】:

按照 Paul Abbott 的建议,将代码更改为在 OracleDataReader 和 OracleConnection 上调用 .Dispose()。还将数据库上每个会话的游标数从 50 个增加到 150 个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    相关资源
    最近更新 更多