ASP.NET Oracle会话保持非活动状态并且错误最大超过最大连接时间

时间:2012-12-04 17:18:39

标签: asp.net oracle

我的ASP.NET C#应用程序连接到Oracle数据库,运行存储过程,并返回具有CloseConnection命令行为的阅读器。阅读器本身已被处理但是 - Oracle会话在V $ SESSION中保持不活动状态。几个小时后,当另一个客户使用该应用程序时,这会变成错误,我们收到错误“ORA-02399:超过最大连接时间,您正在注销”。进一步尝试连接到Oracle返回'ORA-01012:未登录'

这是连接字符串:

User Id=UserID;Password=userPass;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)  (HOST=IP.IP.IP.IP)(PORT=XXXX))(CONNECT_DATA=(SID=SID)));;Max Pool Size=5;Connection Timeout=60;Connection Lifetime=120;

以下是阅读器的使用方法:

using (OracleDataReader dr = OraFunctions.ExecuteReader(input.ConnectionString,
                                                                    CommandType.Text,
                                                                    input.SqlStmt,
                                                                    null))
{
 while (dr.Read())
 {
 //do stuff here 
 }
 dr.Dispose();
}

这是连接到Oracle的类:

public static OracleDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, OracleParameter[] commandParameters) {
        OracleConnection connection = null;
        OracleCommand command = new OracleCommand();
        try {
            connection = new OracleConnection(connectionString);
            connection.Open();
            command.Connection = connection;
            command.CommandType = commandType;
            command.CommandText = commandText;

            if (commandParameters != null) {
                foreach (OracleParameter param in commandParameters) {
                    command.Parameters.Add(param);
                }
            }
            //Passing CommandBehavior.CloseConnection flag to the ExecuteReader method makes the DataReader connection to be closed when the DataReader is closed. 
            OracleDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            command.Dispose();
            return reader;
        } catch {
            if (connection != null) {
                command.Dispose();
                connection.Close();                    
            }
            throw;
        }
    }

我正在寻找关于为什么连接没有实际关闭的任何提示。我正在使用Oracle.DataAccess.Client。我的猜测是datareader的命令行为不起作用,我需要将其重新编码为数据集,我可以在其中明确地关闭连接而不必依赖CommandBehavior。

思考?谢谢!

3 个答案:

答案 0 :(得分:1)

因为你有connection.Open();

为什么没有正确关闭它?

答案 1 :(得分:0)

我们永远无法解决这个问题。我们最终禁用了连接池,而开放/非活动会话在Oracle中消失了。如果有人读到这篇文章并对出了什么问题提出建议,我一定会感激您的意见。

答案 2 :(得分:0)

我现在正在评估的可能解决方案是将Connection Lifetime参数设置为低于服务器的值。

这个想法是在执行查询后连接返回池中,检查生命周期,如果满足两个条件则关闭连接:

  • 连接的生命周期超过Connection Lifetime参数值
  • 打开的连接数不会低于Min Pool Size参数值

感谢Joao Morais了解ODP.NET池细节。