あなたの質問の例は、ロックの順序がアクセス方法に依存することを示しています。このアクセスパスは、クエリのORDER BY句によって直接決定されるのではなく、このアクセスパスに影響を与える可能性のある多くの要因があります。したがって、2つの異なるアクセスパスを持つ可能性があるため、ORDERBYを追加するだけではデッドロックを防ぐことはできません。実際、順序を指定してテストケースを実行し、セッションパラメータを変更することで、同じクエリで2つのセッションをORA-60に実行させることができました。
関連するセッションに保留中の他のロックがない場合は、同じ順序で行をロックします すべてのセッションでデッドロックを防ぐことができますが、どうすればこの順序を確実に強制できますか?これは、とにかくデッドロックのこの非常に特殊なケースを防ぐだけであることに注意してください。各セッションまたは異なるプランで複数のクエリを実行すると、デッドロックが発生する可能性があります。
実際には、このケースは本当に特殊であり、とにかく頻繁に発生することはありません。デッドロックが心配な場合でも、デッドロックを防ぐためのより簡単な方法があると思います。
デッドロックを防ぐ最も簡単な方法は、FOR UPDATE NOWAIT
のいずれかを使用することです。 またはFOR UPDATE WAIT X
(WAIT Xは、デッドロック検出メカニズムよりも優れたXの値でデッドロックをトリガーできますが、現在11gの時点で3秒だと思います-ありがとう @ APC
訂正のために)。
言い換えると、両方のトランザクションで次のように尋ねる必要があります。これらの行を指定してロックしますが、別のユーザーがすでにロックを持っている場合は、無期限に待機するのではなく、エラーを返します。デッドロックを引き起こすのは無期限の待機です。
実際には、実在のユーザーを使用するほとんどのアプリケーションは、トランザクションが別のトランザクションの終了を無期限に待機するよりも、すぐにエラーを受け取る方がよいと思います。 FOR UPDATE
を検討します NOWAIT
なし 重要でないバッチジョブの場合のみ。