私は、スレッド化にTPLライブラリを使用している.NET 4 C#サービスを持っています。 1つの接続が処理用のボトルネックになっていたため、最近は接続プーリングも使用するように切り替えました。マルチスレッドサービスでのデータベース接続プーリング
以前は、接続オブジェクトのスレッドの安全性を制御するためにlock句を使用していました。作業がバックアップされると、キューはタスクとして存在し、多くのスレッド(タスク)がロック句を待機します。現在、ほとんどのシナリオでは、スレッドはデータベースIO上で待機し、プロセスを非常に高速に処理します。
ただし、接続プールを使用しているので、新しい問題があります。接続の最大数に達すると(デフォルトは100)、さらに接続が要求されるとタイムアウトが発生します(Pooling info参照)。この場合、「接続要求がタイムアウトしました」という例外がスローされます。
私のすべてのIDisposablesはステートメントを使用しています。私は接続を正しく管理しています。このシナリオは、プールが処理できる(期待されている)よりも多くの作業が要求されているために発生します。私はこの例外がなぜスローされるのか理解し、それを処理する方法を認識しています。単純なリトライはハックのように感じます。また、接続文字列を使用してタイムアウト時間を増やすこともできますが、これは固いソリューションのようには感じられません。以前の設計(プーリングなし)では、アプリケーション内のロックのために作業項目が処理されていました。
このシナリオを処理してすべての作業が確実に処理されるようにするにはどうすればよいでしょうか?あなたは次のようにParallel.ForEach()
方法を使用して並列度を制御するために見ることができる
あなたはあなたのコードの一部を投稿することができますか?タスクの作成方法とスケジューリング方法を確認すると便利です。 –
タスクは、おおよそ次のように作成されます。Task.Factory.StartNew(()=> ProcessItem(item));私はタスクの作成を制限するのに十分なタスクオブジェクトを追跡していません(それがあなたが考えていたルートの場合)。すべてのタスクがデータベース作業を必要とするわけではなく、すべてのデータベース作業が同じデータベースを使用しているわけではありません(多くの異なるoracle、mssqlなどがあります)。 –
これは負荷の急上昇を処理するためのものですか、または要求が絶えず速すぎて処理できないのですか?後者の場合、ある時点で敗北を認め、失敗を返さなければなりません。 –