(牽引力が得られなかった Server Fault からの相互投稿): 予期しないエラーが原因で Web 要求が終了した後、ASP .NET セッション状態がロックされたままになる根本的な原因を突き止めようとしています。Web ファームに複数のサーバーがあるため、セッションには SQL Server セッション状態プロバイダーを使用します。この問題は、明確な理由もなく、多くのリクエストがライフサイクルの「AcquireRequestState」イベントで停止するという形で最初に現れました。SQL サーバーのセッション状態データベースで、これらの要求に対応するエントリを見つけることができましたが、それらはすべてロックされていました (列 Locked = 1)。また、これらのリクエストを IIS ログの HTTP ステータス コード 500 (サブ ステータス 0) のエントリに関連付けることもできました。これらの調査結果から、場合によっては、
問題の Web サイトのステータス コード 500 に対して、IIS で失敗した要求トレースを有効にし、使用可能なすべてのプロバイダーを詳細度の「詳細」設定でそれぞれ選択しました。それ以来、ASP .NET セッションが永続的にロックされる原因となったいくつかの失敗したトレースを収集しました。それらはすべて同じ特性を共有しています。
- それらはすべて、ブラウザが処理/保存するデータを投稿する「POST」リクエストです。
- それらはすべて、REQUEST_ACQUIRE_STATE イベント中に「Session」モジュールが呼び出されたことを示すイベントを持っています。この時点で、要求はセッション状態データベースの行を「ロック済み」としてマークします。これは正常であり、予期されたものです。
- それらはすべて、要求の一部としてサーバーに投稿されたデータを読み取っているように見える GENERAL_READ_ENTITY_START、GENERAL_READ_ENTITY_END、および GENERAL_REQUEST_ENTITY エントリを持っています。これらのイベントは、ポストされたデータのサブセットを読み取るたびに何度も繰り返されるため、バッファリングされた操作のように見えます。
- 「エンティティの読み取り」関連イベント中のある時点で、エラーが発生します。一部のエラー コードは「関数が正しくありません。(0x80070001)」であり、他のエラー コードは「スレッドの終了またはアプリケーション要求のため、I/O 操作が中止されました。(0x800703e3)」です。
- エラーが発生すると、それらはすべて END_REQUEST イベントに直接ジャンプします。
ここでの問題は、通常の状況では、Session モジュールがセッションで保持しているロックを解放できるようにする RELEASE_REQUEST_STATE イベントが存在する必要があることです。このシナリオでは、このイベントはスキップされています。念のため、'200' ステータス コードの失敗したリクエストのトレースも有効にし、Session モジュールによって処理される RELEASE_REQUEST_STATE イベントを持つ成功したリクエストのトレースをいくつか生成しました。
同僚は、HttpContext.Current.ApplicationInstance.CompleteRequest() を呼び出して、リクエストを直接 'END_REQUEST' イベントにスキップさせることもできると指摘しました。これをテストしたところ、投稿リクエスト中にこのメソッドを使用すると、この問題が発生したときにキャプチャしたものと非常によく似たトレースが作成されることがわかりましたが、セッションは引き続き適切にクリーンアップされます。これにより、セッションが保存されている SQL Server データベースで SQL Profiler を実行して、ストアド プロシージャへのすべての呼び出しをトレースすることになりました。CompleteRequest() の呼び出しにより END_REQUEST に直接スキップすると、期待どおりにセッション状態を更新する (およびロックを解放する) 呼び出しが行われます。GENERAL_REQUEST_ENTITY 中のエラーの結果として END_REQUEST にスキップすると、セッション状態のロックを更新または解放するための呼び出しは行われません。
この時点での私の理論は、ある種のネットワークの問題が「不正な機能」と「スレッドの終了またはアプリケーション要求のいずれかにより I/O 操作が中止されました」というエラーを引き起こしているということですが、なぜこれが見えるのかわかりませんリクエスト処理がセッション状態のロックの解放をスキップする原因となります。リクエストが REQUEST_ACQUIRE_STATE を通過した場合、リクエストの終わりに向かってある時点でロックも解放する必要があるようです。これが IIS または ASP .NET のバグだとは言いたくないのですが、現時点では確かにそのように見えます。
エラーによってセッション状態のロックが解除されない既知の条件はありますか?