我的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。
思考?谢谢!
答案 0 :(得分:1)
因为你有connection.Open();
为什么没有正确关闭它?
答案 1 :(得分:0)
我们永远无法解决这个问题。我们最终禁用了连接池,而开放/非活动会话在Oracle中消失了。如果有人读到这篇文章并对出了什么问题提出建议,我一定会感激您的意见。
答案 2 :(得分:0)
我现在正在评估的可能解决方案是将Connection Lifetime
参数设置为低于服务器的值。
这个想法是在执行查询后连接返回池中,检查生命周期,如果满足两个条件则关闭连接:
Connection Lifetime
参数值Min Pool Size
参数值感谢Joao Morais了解ODP.NET池细节。