liguofeng29’s blog

個人勉強用ブログだっす。

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 が返されたトランザクション側でコミット、

もしくは、ロールバックを実行する必要があります。なお、どちらを行なうべ

きかは運用形態に(アプリケーションの仕様)に依存します。