Oracle - デットロック(dead lock)
[Problem]
デッドロック発生後のが検出された後、トランザクションはどうなりますか?
[Cause]
デッドロックが検出され ORA-60 が発生した場合、当該のSQL文の処理は無
効になります。しかし、そのSQL文以前に実行された処理(同一トランザク
ション内の別の処理)はコミットもロールバックもされ無い状態で残ります。
下記の様な表(test)に対して、最も単純なデッドロックが発生する場合を想
定して説明します。
C1 C2
---------- ----------
1 1
2 2
3 3
4 4
実行されるトランザクションは下記の2つで、文の左側についている番号の順
序で処理が行なわれるとします。
1. UPDATE test SET c2 = 99 WHERE c1 = 1;
2. UPDATE test SET c2 = 99 WHERE c1 = 2;
5. UPDATE test SET c2 = 99 WHERE c1 = 3;
ORA-00060: リソース待機の間にデッドロックが検出されました。
3. UPDATE test SET c2 = 0 WHERE c1 = 4;
4. UPDATE test SET c2 = 0 WHERE c1 = 3;
6. UPDATE test SET c2 = 0 WHERE c1 = 2;
1. から 4. 迄の処理が問題なく行われると、5. の処理で待ちが発生します。
そして、次に 6. の処理が実行されるとデッドロックが完成します。この時、
6. は待ち状態になり、逆にそれまで待ち状態であった 5. の処理に ORA-60
が返されます。
この時、トランザクション2は引き続き待ちの状態であり、コミットもロール
バックも行われていない状態にあります。
一方、ORA-60 が返されたトランザクション1では、エラーが発生した 5. の
処理は無効になりますが、1. 及び 2. の処理はそのままの状態で残されるこ
とになります。この為、トランザクションとしてはコミットもロールバックも
行われていない状態になります。
[Action]
処理を継続する為には、ORA-60 が返されたトランザクション側でコミット、
もしくは、ロールバックを実行する必要があります。なお、どちらを行なうべ
きかは運用形態に(アプリケーションの仕様)に依存します。