Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用ODP.NET C#OracleDataReader的最大开放游标ORA-01000_C#_Asp.net_Oracle_Odp.net - Fatal编程技术网

使用ODP.NET C#OracleDataReader的最大开放游标ORA-01000

使用ODP.NET C#OracleDataReader的最大开放游标ORA-01000,c#,asp.net,oracle,odp.net,C#,Asp.net,Oracle,Odp.net,我正在使用Oracle Data Provider for.NET 4.112.3.0版从ASP.NET web应用程序访问Oracle 9数据库。即使我显式地OracleDataReader和OracleConnection对象的Close和Dispose,我仍会收到ORA-01000最大打开游标数,有时会出现错误 我的大部分ODP.NET代码都包装到自定义类中 using System; using System.Collections.Generic; using System.Linq;

我正在使用Oracle Data Provider for.NET 4.112.3.0版从ASP.NET web应用程序访问Oracle 9数据库。即使我显式地
OracleDataReader
OracleConnection
对象的
Close
Dispose
,我仍会收到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\u CURSORS
参数设置为100。对于给定的查询调用,我注意到这个简单的select查询有92个打开的游标,有时会突破100个游标的限制!为什么在使用
OracleDataReader
时会打开如此多的游标


注意,我已经在一个运行WindowsServer2012和IIS8.0的开发系统上测试了这一点。使用
OracleConnection
完成后,我还调用了
OracleConnection.ClearAllPools
方法,但这似乎也没有什么帮助。我还通过使用
Fill
方法和
OracleDataAdapter
填充
DataTable
对象来测试查询。使用此方法仅打开3个游标。为什么打开的游标数量会有这样的变化?

为什么需要为select?@Dr.Stitch打开一个事务?MyOracleClass中有另一个方法调用ExecuteOnQuery进行插入/删除/更新,因此OracleTransaction用于提交和回滚。为了简洁起见,我删除了代码。