6

リリースイット!、Michael Nygard は、壊滅的なシステム障害の多くは、一連の不具合が原因であることが多いと説明しています。たとえば、2 つのスレッドがデッドロックします。スレッド プール内のスレッドが 2 つ少なくなったため、他のスレッドの負荷が増加し、デッドロックの可能性が高くなります。突然、サーバーがまったく応答しなくなります。これは、スレッド プールが使い果たされ、ロード バランサーが他のサーバー (すべて同じコードを実行している) にトラフィックを迂回させ、デッドロックの可能性を高めるためです。突然、ファーム全体がオフラインになります。

ほとんどの RDBMS サーバーはデッドロックを検出し、「敗者」を決定します (一方のトランザクションは中止され、もう一方は続行できます)。対照的に、C# では、lockステートメントはロックが取得されるまで無期限に待機します。

ただし、Monitor.TryEnter(lockObject, TimeSpan)を呼び出して、ロックまたはタイムアウトを要求することはできます。タイムアウトが経過し、ロックを取得できなかった場合は false を返します。これを using ステートメントでラップして、適切な構文を維持するものもあります。

私の質問は、常にタイムアウトを使用してロックを取得しますか? また、デッドロック シナリオと比べて、タイムアウトはどのような問題を引き起こすのでしょうか?

4

4 に答える 4

6

私は通常、タイムアウトを使用します。ここでの最大の問題は、タイムアウトに達すると、要求している操作が中止されることです。これは明らかにデッドロックよりも好ましい方法です。ただし、そこにはもっと大きな問題があります。操作が重要であり、他の何かがデッドロックされているために中止を開始した場合、設計が適切でない場合、この方法で説明したファームがダウンする問題が発生する可能性があります (よりソフトですが:アプリは動作しなくなりますが、コントロールを失ったわけではありません)。

主な違いは、ここでは実際に制御できることですが、スレッドがデッドロックを開始した場合、障害が発生すると問題を解決するためにコード内でできることは何もありません。

于 2009-01-30T19:52:46.040 に答える
1

ロックの試行がタイムアウトした状況から正常に回復できますか? 可能であれば、必ずタイムアウトを使用してください。できない場合は、タイムアウトする意味があまりありません。実行を再開したらどうしますか? せいぜい、エラー メッセージで終了できます。タイムアウトには用途がありますが、微妙なスレッドのバグを隠す方法としても使用できるため、注意して使用することをお勧めします。

于 2009-01-30T19:58:01.070 に答える