Max Open Cursors ORA-01000使用ODP.NET C#OracleDataReader

时间:2016-06-29 01:15:42

标签: c# asp.net oracle odp.net

我使用Oracle Data Provider for .NET 4.112.3.0版从ASP.NET Web应用程序访问Oracle 9数据库。即使我明确CloseDispose OracleDataReaderOracleConnection个对象,我有时会收到ORA-01000最大打开游标错误。

我的大部分ODP.NET代码都包含在自定义类中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Oracle.DataAccess.Client;
using System.Data;

namespace MyNamespace
{
    public class MyOracleClass : IDisposable
    {
        private static string connectionString = "Data Source=myDB;Persist Security Info=True;User ID=myUser;Password=myPassword;";
        private OracleConnection _conn;
        private OracleTransaction _txn;

        public MyOracleClass()
        {
            try
            {
                _conn = new OracleConnection(connectionString);
                if (_conn.State != ConnectionState.Open)
                    _conn.Open();
                _txn = _conn.BeginTransaction(IsolationLevel.ReadCommitted);
            }
            catch (Exception ex)
            {
                // Log Exception
                throw ex;
            }
        }

        public void Query(string query, ref OracleDataReader dr)
        {
            dr = null;
            OracleCommand cmd = null;

            try
            {
                if (_conn.State != ConnectionState.Open)
                    _conn.Open();
                cmd = new OracleCommand(query, _conn);

                dr = cmd.ExecuteReader();
            }
            catch (Exception ex)
            {
                // Log Exception    
                throw ex;
            }
            finally
            {
                if (cmd != null)
                    cmd.Dispose();
            }
        }

        public void Disconnect()
        {
            try
            {
                if (IsConnectionOpen())
                {
                    _txn.Rollback();
                    _conn.Close();
                }
            }
            catch (Exception ex)
            {
                // Log Exception
            }
        }

        public void Dispose()
        {
            Disconnect();

            try
            {
                if (this._txn != null)
                {
                    _txn.Dispose();
                    _txn = null;
                }
            }
            catch (Exception ex)
            {
                // Log Exception
            }

            try
            {
                if (this._conn != null)
                {
                    this._conn.Dispose();
                }
            }
            catch (Exception ex)
            {
                // Log Exception
            }
        }

        public bool IsConnectionOpen()
        {
            if (this._conn.State == ConnectionState.Open)
            {
                return true;
            }

            return false;
        }
    }
}

然后我在我的程序中使用该类。

public void test()
{
    OracleDataReader dr = null;
    MyOracleClass oracleDb = null;
    string query = "SELECT COL_1, COL_2, COL_3 FROM MY_TABLE";

    try
    {
        oracleDb = new MyOracleClass();
        oracleDb.Query(query, ref dr);

        if(!dr.HasRows)
        {
            // No data found
        }
        else
        {
            while(dr.Read())
            {
                // Process data
            }
        }
    }
    catch(Exception ex)
    {
        // Log Exception
    }
    finally
    {
        if(dr != null)
        {
            dr.Close();
            dr.Dispose();
        }

        oracleDb.Dispose();
    }
}

我的查询平均返回500行。当我第一次遇到这个问题时,我决定去数据库查看实际打开的游标数量。我的数据库的OPEN_CURSORS参数设置为100.对于给定的查询调用,我注意到这个简单的select查询有92个打开的游标,有时会打破100个游标限制!使用OracleDataReader

时,为什么会打开如此大量的游标?

注意,我一直在运行带有IIS 8.0的Windows Server 2012的开发系统上测试它。我在使用OracleConnection.ClearAllPools完成后也调用了OracleConnection方法,但这似乎也没有帮助。我还通过使用DataTable方法和Fill填充OracleDataAdapter对象来测试查询。使用此方法仅打开3个光标。为什么打开游标的数量有这么大的差异?

0 个答案:

没有答案