私の 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 に依存せずに接続を明示的に閉じることができるデータセットとしてこれを再コーディングする必要があります。
考え?ありがとう!