ORA-00604,与Oracle的C#中的ORA-01000错误;超出最大开放游标数

时间:2017-03-27 20:15:57

标签: c# oracle oracle11g

大家好:我有一个程序运行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:超出最大打开游标数。我有什么想法我做错了吗?

1 个答案:

答案 0 :(得分:0)

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