【问题标题】:Open another conection in OracleDataReader loop the oracle session not close在 OracleDataReader 中打开另一个连接循环 oracle 会话未关闭
【发布时间】:2016-10-20 21:16:43
【问题描述】:

在下面的 OracleDataReader 循环代码下调用另一个连接时,我遇到会话未关闭的问题

    private ArrayList GetORA()
    {          
        ArrayList arr = new ArrayList();
        string connectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=xx)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)));User ID=kcdev2usr;Password=password;ENLIST=FALSE;Pooling=true;Max Pool Size=20;";
        const string queryString = "select * from MASTER_TABLE";
        using (OracleConnection connection = new OracleConnection(connectionString))
        {
            OracleCommand command = new OracleCommand(queryString, connection);
            connection.Open();
            OracleDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            try
            {
                while (reader.Read())
                {
                    Master m = new Master();
                    m.ID = reader["ID"].ToString();
                    m.obj = GetAnother(reader["SOME"].ToString());
                    arr.Add(m);
                }
            }
            finally
            {
                reader.Close();
            }

        }

        return arr;
    }


    private Object GetAnother(string some)
    {
        // Do something         
        string getNextID = PutSome(some);
        //=====
        Object obj = null;
        string connectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=xx)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)));User ID=kcdev2usr;Password=password;ENLIST=FALSE;Pooling=true;Max Pool Size=20;";
        const string queryString = "SELECT PAGE_NAME FROM ANOTHER_TABLE WHERE ID=:ID";
        using (OracleConnection connection = new OracleConnection(connectionString))
        {
            OracleCommand command = new OracleCommand(queryString, connection);
            command.Parameters.Add("ID",getNextID);
            connection.Open();
            OracleDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            try
            {
                while (reader.Read())
                {
                    obj = CreateObj(dr["PAGE_NAME"].ToString());
                }
            }
            finally
            {
                reader.Close();
            }
        }

        return obj;
    }

session is not close

然后,..我尝试像这样将问题方法移出循环

private ArrayList GetORA()
    {          
        ArrayList arr = new ArrayList();
        string connectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=xx)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)));User ID=kcdev2usr;Password=password;ENLIST=FALSE;Pooling=true;Max Pool Size=20;";
        const string queryString = "select * from MASTER_TABLE";
        using (OracleConnection connection = new OracleConnection(connectionString))
        {
            OracleCommand command = new OracleCommand(queryString, connection);
            connection.Open();
            OracleDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            try
            {
                while (reader.Read())
                {
                    Master m = new Master();
                    m.ID = reader["ID"].ToString(); 
                    m.Some = reader["SOME"].ToString();                     
                    arr.Add(m);
                }
            }
            finally
            {
                reader.Close();
            }
           foreach (var item in arr)
           {
                item.obj = GetAnother(item.Some);
           }
        }

        return arr;
    }

所有的 oracle 会话都正确无误,为什么?

  • 我觉得我的代码不好,但我想知道 ODP.Net 管理 oracle 会话有什么不同。

ps。我使用“Oracle.DataAccess.dll”版本 4.121.2.0

【问题讨论】:

    标签: c# oracle session odp.net


    【解决方案1】:

    您可能会看到连接池 - “使用”调用 dispose 将连接返回到池但不会关闭它。您可以在连接字符串中设置“pooling=false”来确认,但没有什么理由将其关闭。

    由于 oracle 减小池大小的方式,您的第二个循环可能会有所不同:

    https://docs.oracle.com/cd/B28359_01/win.111/b28375/featConnecting.htm#i1006393

    也就是说,我只是让池做它应该做的事情。我倾向于添加的唯一内容是“最小池大小 = 0”。如果应用完全空闲,这可确保池变为 0,并有助于防止池中出现陈旧的连接。

    【讨论】:

      【解决方案2】:

      如果你想结束会话,你应该打电话给connection.Dispose();

      http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/hol08/dotnet/getstarted-c/getstarted_c_otn.htm

      但是为什么要循环关闭会话呢? 开放会话是一项昂贵的操作,而墓葬更好的规则是多次重用一个连接。 Oracle 允许您使用一个用户/通行证到多个会话。也许你应该考虑一下。

      【讨论】:

      • 不需要显式调用 Dispose(),因为 using 语句会处理这个问题
      • 是的,我想重用会话,但是几天后我无法优化旧代码(这是一个旧应用程序),因此需要一些快速的解决方案来更改这个,然后再修改整个源代码
      猜你喜欢
      • 2012-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多