在OracleDataReader循环中打开另一个连接,oracle会话不关闭

时间:2016-10-16 16:18:09

标签: c# oracle session odp.net

当在下面的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

2 个答案:

答案 0 :(得分:0)

You are likely seeing connection pooling - the "using" calls dispose which returns the connection to the pool but does not close it. You can set "pooling=false" in your connection string to confirm, but there is little reason to turn it off.

Your second loop might be acting differently because of the way oracle decreases the pool size:

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

That said, I would just let pooling do what it is supposed to do. The only thing I tend to add is "min pool size=0". This makes sure the pool goes to 0 if the app is completely idle and helps protect against getting stale connections in the pool.

答案 1 :(得分:-1)

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

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

但是为什么要在循环中关闭会话? 开放会话是昂贵的操作,更好的坟墓规则是重复使用一个连接。 Oracle允许您使用一个用户/传递给多个会话。也许你应该考虑一下。