RabbitMQ を介してメッセージを受信する Windows サービスがあります。これにより、何らかの作業を行うイベント ハンドラーがトリガーされ、結果をデータベースに永続化しようとします。以下を使用してスレッド化されています。
ThreadPool.QueueUserWorkItem(ProcessMessageOnThread, messageReceived);
ここで、RabbitMQ からデキューされたメッセージの表現である でProcessMessageOnThread
作業を行うメソッドです。messageReceived
通常の状況では、Windows サービスは期待どおりに動作しました。つまり、デキュー、プロセス、および永続化です。
すべてのメッセージが処理され、適切な変更が処理されるようにしたいので、SQL Server への接続を開くことができない場合は、メッセージを再度キューに入れ、再度処理できるようにします (うまくいけば、そのとき SQL Server はそうしないと、これが続きます-そして私はそれで問題ありません)。
プロセスが一定期間期待どおりに実行されていたときに問題が発生し、SQL Server 接続プールがいっぱいになり、 SQL Server が切断されました。これは、状況が少し不安定になったときです。
次の 2 つのいずれかが発生する可能性があります。
例外がスローされます
connection.Open()
-しかし、私はこれをキャッチしているので、心配していませんcmd.ExecuteNonQuery()
ストアドプロシージャを実行している場所で例外がスローされます
これは、処理方法を理解する必要がある 2 番目のオプションです。以前は、ここで例外が発生した場合、ストアド プロシージャに渡したデータに問題があったため、データをキューから移動し、別の方法で分析する必要があると考えていました。
ただし、実際には接続が確立されていない場合に例外が発生する場合を処理するには、新しいアプローチが必要だと思います。
クラスを調べたところ、この説明を持つSqlException
プロパティが呼び出されていることに気付きました。これに関する情報には次のように記載されています。Class
Gets the severity level of the error returned from SQL Server
重大度レベルが 10 以下のメッセージは情報提供を目的としており、ユーザーが入力した情報の間違いによって引き起こされた問題を示しています。11 から 16 までの重大度レベルはユーザーが生成し、ユーザーが修正できます。17 ~ 25 の重大度レベルは、ソフトウェアまたはハードウェアのエラーを示します。レベル 17、18、または 19 のエラーが発生した場合、特定のステートメントを実行できない場合がありますが、作業を続行できます。
これは、ストアド プロシージャに不正な形式のデータが送信される可能性が最も高いためif (ex.Class > 16)
、接続に問題があるため、メッセージをチェックしてから再キューイングできる例外処理を修正することを意味しますか?else
したがって、問題は、例外処理をどのように行うべきか、およびcmd.ExecuteNonQuery()
スローされた例外が接続の切断によるものであるかどうかを呼び出すときにどのように検出できるかです。
アップデート:
接続がプールに返されないという問題が以前に発生し (これはスレッドの問題が原因でした)、これらの問題を修正したので、問題は接続がプールに戻らないこととは関係がないと確信しています。また、接続が使用されている目的に関するロジックは非常に単純であり、それらが一貫して閉じられていることを確認しています...したがって、Sqlサーバーの切断と動作のキャプチャに関する回答にもっと興味がありますcmd.ExecuteNonQuery() の