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)
- ORA-00060 エラーは単発で発生することがありますか?
-
はい、単発で発生する場合もあります。特に短時間でトランザクションが競合した場合や、バッチ処理中にロックの順序が一致しなかった場合には、一度だけ発生して正常に処理が終わることもあります。ただし、頻発する場合はトランザクション設計やロック順序に根本的な問題がある可能性があります。
- Oracle 以外のデータベースでも同様のデッドロックエラーは発生しますか?
-
はい、Oracle 以外の主要なRDBMS(例:MySQL、PostgreSQL、SQL Server)でもデッドロックは発生します。どのデータベースも複数のトランザクションが同じリソースへ同時にアクセスしようとするとロック競合が起き、デッドロックを検出して一方をロールバックする仕組みがあります。したがって、アプリ設計でのロック順序やトランザクション設計の工夫がどのDBでも重要です。
- デッドロックを完全に防ぐことはできますか?
-
完全に防ぐことは理論上難しいですが、実務レベルではほぼ防ぐことが可能です。代表的な対策としては、処理するレコードの並びを統一して常に同じ順序でロックする、不要にトランザクションを開きっぱなしにしない、更新対象を明確に分けるなどがあります。これらを徹底することでデッドロックの発生頻度を大幅に下げられます。
✅ まとめ
| ポイント | 内容 |
|---|---|
| 原因 | トランザクション同士が相互待ち状態 |
| 検出後 | Oracleが一方をロールバック |
| 対策 | ロック順序統一、リトライ処理、短いトランザクション |
| 調査 | トレースファイル + v$session等 |
デッドロックはアプリ設計と運用改善で防げます。
DBの問題と思われがちですが、多くはアプリ側のトランザクション管理が原因です。



