SQL Serverには別のスレッドがあり、定期的に(デフォルトでは5秒、デッドロックが検出された場合は間隔が狭く)サイクルの待機リストをチェックします。つまり、スレッドが待機しているリソースを識別し、そのリソースの所有者を見つけ、そのスレッドが順番に待機しているリソースを再帰的に見つけて、他の各リソースを待機しているスレッドを識別します。
デッドロックが見つかった場合、このアルゴリズムを使用して犠牲者が強制終了されます。
- 強制終了できないスレッドを識別します(たとえば、トランザクションをロールバックしているスレッドは強制終了できません)。
- デッドロックの優先順位が最も低いスレッドを見つけます。
- ロールバックが最も安価なもの、つまり、これまで作業が最も少ないものを選択しました。
あなたはここにSQLサーバーのデッドロック検出に関する詳細な情報を見つけることができます:
http://msdn.microsoft.com/en-us/library/ms178104.aspx
トランザクションの所有者/アプリケーション開発者は、デッドロックが発生するリスクを最小限にするための責任がある、とやって彼らがすべきこと:
- トランザクションはできるだけ短くしてください。たとえば、トランザクションの開始後にログインフォームを表示せず、ユーザーの入力を待つ代わりに、必要な情報をすべて収集してからトランザクションを実行します。
- 可能な限り低い分離レベルを使用します。たとえば、一時的にユーザーにいくつかの値を表示したいだけの場合は、シリアライズ可能に設定しないでください。正しい分離レベルを設定すること自体は科学であり、この回答の範囲外であることに注意してください。
- デッドロックの被害者である場合、つまりエラー番号1205が発生した場合は、トランザクションをユーザーに対して透過的に再実行します。もう1つの競合するトランザクションが、待機して終了していたリソースをうまく取得できたので、同じデッドロックが再び発生する可能性はほとんどありません。