ORA-00060: deadlock detected while waiting for resource は、Oracleデータベースが相互にロックし合う処理を検出し、処理を強制終了した際に発生するエラーです。トランザクション同士が互いに待ち状態に陥る**デッドロック(Deadlock)**が原因です。
本記事では、ORA-00060 の発生条件、よくある原因、デバッグ方法、実践的な対処策を詳しく解説します。
✅ ORA-00060とは?エラー概要
| 項目 | 内容 |
|---|---|
| エラーコード | ORA-00060 |
| 意味 | デッドロックが検出された |
| 発生タイミング | ロック競合により処理が行き詰まった時 |
| 対応 | 片方のSQLを強制ロールバック、アプリ側は例外処理 |
Oracleはデッドロックを検知すると一方のトランザクションを自動的にロールバックし、システム全体の停止を防ぎます。
✅ デッドロックが起こる典型例
パターン1:同じテーブルの行を別順にロック
片方が row1、もう片方が row2 を先にロックし、互いに次のリソースを待つ状態になる例です。
パターン2:未コミットの長時間処理
-
更新処理をコミットせず放置
-
バッチ処理中に他の処理が割り込む
パターン3:アプリ側でロック順序の不一致
-
更新対象リストをソートせず更新
-
並列処理スレッドで異なる順番で更新
✅ 再現例(簡易デモ)
セッションA
セッションB
この状態でお互いのロックを待ち合うとデッドロック発生。
✅ デッドロック解析:trace file の場所と見方
Oracleはデッドロック検出時にアラートログとトレースファイルを出力します。
トレースファイル例
パス例:
内容には以下が記録:
-
SQL文
-
セッション情報
-
ロック対象オブジェクト
-
相手セッション情報
デバッグポイント:
-
同じ行/テーブルを複数処理が更新していないか
-
並列バッチやトランザクション処理の順序
✅ 対策:アプリ側 & DB側のアプローチ
✅ 1. ロック順序を統一する(最重要)
複数行更新する場合はIDソートして更新するなど、順序を固定。
✅ 2. こまめに COMMIT / ロック保持時間を短縮
-
不要なトランザクションを開きっぱなしにしない
-
大量更新は小分け
✅ 3. 再試行ロジック(リトライ処理)
アプリ側で例外時にリトライする仕組み
✅ 4. 排他制御の明確化
-
SELECT … FOR UPDATE の利用
-
アプリの排他設計見直し
✅ 5. 監視・ログ出力の強化
-
SQLログ
-
ロック監視ビュー(
v$lock,v$session,v$transaction)
✅ まとめ
| ポイント | 内容 |
|---|---|
| 原因 | トランザクション同士が相互待ち状態 |
| 検出後 | Oracleが一方をロールバック |
| 対策 | ロック順序統一、リトライ処理、短いトランザクション |
| 調査 | トレースファイル + v$session等 |
デッドロックはアプリ設計と運用改善で防げます。
DBの問題と思われがちですが、多くはアプリ側のトランザクション管理が原因です。
