質問: 同じselect文同士でのデッドロックが発生 oracle10gを使用したアプリ開発中です。 アプリ中、1テーブルに対して全く同じ条件で 複数レコードを悲観的ロック(for update)しながら取得し、 項目を更新するsqlを発行します。 単発では問題なかったのですが、処理時間の関係で パラレルで実行された場合にデッドロックを検出することがあります。 oracleのudumpの中を確認すると全く同じselectのsql同士で デッドロックが発生したと表示されています。 こういった場合、どういう原因が考えられるでしょうか? (同じ条件による悲観的ロックであれば多重実行でも 処理待ちをするだけだと思っているのですが・・・) よろしくお願いします。
回答: 下記タイミングで処理されるとデットロックします。 1.aがレコードのロック状態を検査。ロック無しと判定 2.bがレコードのロック状態を検査。ロック無しと判定 3.aがレコードをロック 4.bがレコードを再ロック 5.aが更新の為にレコード取得を試みる。が、4でbにロックされている為、ロックが解除されるまで処理待ち 6.bが更新の為にレコード取得を試みる。が、3でaにロックされている為、ロックが解除されるまで処理待ち 7.めでたくデットロック 実際の処理では、レコードのロック以外に、テーブルのロック、システムテーブルのレコードロックとかも行うので、レコードロックとテーブルロックなどがかち合って、もっと楽しい事(※)が起きます(笑) (※)サーバーをリブートしないと復活しないとか、サーバーをリブートしても復活しないとか、色々。起きると死にそうな目に遭う。