26

Oracle 10g をホストする AIX サーバー上で一連のスクリプトを nohup として並行して実行しています。これらのスクリプトは他の誰かによって書かれており、同時に実行されることを意図しています。すべてのスクリプトがテーブルで更新を実行しています。私はエラーが発生しています、

ORA-00060: リソースの待機中にデッドロックが検出されました

これをグーグルで検索したところ、 http://www.dba-oracle.com/t_deadly_perpetual_embrace_locks.htmが見つかりました

スクリプトは同じテーブルで同時に更新を実行していますが、WHERE句によって決定されたテーブルの異なるレコードで更新を実行しており、それらの間でレコードが重複することはありません。

それで、これはエラーを引き起こしたでしょうか?.

テーブルのどこで更新が実行されても、このエラーは発生しますか?

テーブルでの同時更新を常に避けるべきですか?

PL/SQL successfully completed奇妙なことに、上記の引用されたエラーの後に、nohup.out ログにもありました 。

これは、オラクルがデッドロックから回復し、更新を正常に完了したことを意味しますか?それとも、これらのスクリプトを連続して再実行する必要がありますか? どんな助けでも大歓迎です。

前もって感謝します。

4

4 に答える 4

32

私は最近、同様の問題に苦しんでいました。データベースに外部キーのインデックスがないことが判明しました。これにより、Oracle は必要以上に多くのレコードをロックし、同時実行性が高いとすぐにデッドロックが発生しました。

これは、デッドロックを修正する方法に関する多くの詳細、提案、および詳細を含む優れた記事です: http://www.oratechinfo.co.uk/deadlocks.html#unindex_fk

于 2010-10-25T14:55:04.123 に答える
13

行ロック以外にもデッドロックが発生する可能性があります。たとえば、こちらを参照してください。スクリプトは、インデックス ブロックなどの他のリソースを求めて競合している可能性があります。

私は過去に、互いに近いブロックに影響を与える可能性が低いワークロードの部分で異なるインスタンスが動作するように並列処理を設計することで、これを回避しました。たとえば、大きなテーブルの更新の場合、 のようなものを使用して並列スレーブをセットアップする代わりに、各スレーブが連続したデータ セットで動作することを意味するものをMOD(n,10)使用します。TRUNC(n/10)

もちろん、DBMS_PARALLEL_EXECUTEなど、並列処理のためにジョブを分割するはるかに優れた方法があります。

「PL/SQL が正常に完了しました」というメッセージが表示される理由がわからない場合は、スクリプトが例外を処理している可能性があります。

于 2010-06-19T12:57:14.870 に答える
5

私もこの問題に遭遇しました。実際に何が起こっていたのか、技術的な詳細はわかりません。ただし、私の状況では、根本的な原因は、Oracle データベースにカスケード削除のセットアップがあり、JPA/Hibernate コードもカスケード削除呼び出しを実行しようとしていたことでした。したがって、私のアドバイスは、何が起こっているのかを正確に把握することです。

于 2011-02-03T02:54:41.390 に答える