1

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

考え?ありがとう!

4

3 に答える 3

1

connection.Open(); があるので

なぜ適切に閉じなかったのですか?

于 2014-04-23T09:52:15.283 に答える
0

これを解決することはできませんでした。接続プールを無効にすることになり、Oracle で開いている/非アクティブなセッションがなくなりました。誰かがこれを読んで、何がうまくいかなかったのかについて提案があれば、私は間違いなくあなたの意見に感謝します.

于 2012-12-10T20:36:45.370 に答える
0

私が現在評価している可能な解決策は、Connection Lifetimeパラメーターをサーバーの値より低く設定することです。

アイデアは、クエリの実行後に接続がプールに返されたときに、その有効期間がチェックされ、両方の条件が満たされた場合に接続が閉じられるというものです。

  • 接続の存続期間がConnection Lifetimeパラメーター値を超​​えました
  • Min Pool Size開かれた接続の数は、パラメーター値よりも小さくありません

ODP.NETプーリングの詳細についてJoao Moraisに感謝します。

于 2013-02-12T13:46:07.147 に答える