【Oracle】ORA-01013の原因と解決方法|user requested cancel of current operation・SQLがキャンセル/タイムアウトした時の確認ポイント

【Oracle】ORA-01013の原因と解決方法|user requested cancel of current operation・SQLがキャンセル/タイムアウトした時の確認ポイント Oracle

ORA-01013: user requested cancel of current operation は、Oracleで実行中の処理がキャンセルされた時に表示されるメッセージです。エラー文だけを見るとDB側の障害に見えますが、実務ではSQL Developerの停止ボタン、Ctrl+C、Webアプリやバッチのタイムアウト、JDBC/ODP.NETのキャンセル処理など、クライアント側からの中断が原因になっていることが多いです。

Oracle公式のエラーメッセージでも、原因はユーザーが CTRL-C などのキャンセル操作でOracleの処理を中断したこと、と説明されています。つまり、最初に確認すべきなのは「DBが壊れたか」ではなく「どこからキャンセルが要求されたか」です。

先に結論
ORA-01013は、現在の処理がキャンセルされたことを示すメッセージです。単発で発生し、利用者が明示的に停止しただけなら大きな対応は不要です。一方でWebアプリ、バッチ、帳票、APIで繰り返し発生する場合は、アプリ側タイムアウト、SQLの遅さ、ロック待ち、ネットワーク中断を順番に切り分けます。
スポンサーリンク

ORA-01013とは

ORA-01013は、Oracleが「今実行していた操作はキャンセルされた」と返している状態です。SQLの構文ミスや権限不足のように、SQLそのものが常に間違っているとは限りません。同じSQLでも、手動実行では成功し、アプリ経由では一定秒数後にORA-01013になることがあります。

この場合、SQLの正誤だけでなく、実行経路全体を見ます。たとえば、Webサーバーのリクエストタイムアウト、アプリケーションのクエリタイムアウト、ジョブ管理ツールの制限時間、利用者のキャンセル操作がOracleに伝わると、DB側ではORA-01013として見えることがあります。

単発の手動キャンセル

SQL DeveloperやSQL*Plusで利用者が停止しただけなら、基本的には次の操作へ進めばよいケースです。

一定秒数で毎回発生

30秒、60秒、300秒など決まった秒数で出る場合は、アプリやミドルウェアのタイムアウト設定を疑います。

特定SQLだけで発生

SQLが遅い、実行計画が悪い、ロック待ちしている、取得件数が多すぎる可能性があります。

バッチや帳票で発生

ジョブ管理ツール、帳票サーバー、APIゲートウェイなど、DB以外の制限時間も確認します。

よくある原因

ORA-01013の原因は、画面上では同じメッセージでも発生元が分かれます。特に本番調査では「誰がキャンセルしたのか」「何秒で止まったのか」「DB側では待機していたのか」を分けて見ると、原因に近づきやすくなります。

利用者・開発者が手動で停止した

SQL Developer、A5:SQL、SQL*Plusなどで停止ボタンや Ctrl+C を押したケースです。再実行して成功するなら大きな問題ではありません。

アプリ側のクエリタイムアウト

JDBCの setQueryTimeout、ODP.NETの CommandTimeout、フレームワークのSQLタイムアウトなどが原因です。

Webリクエストのタイムアウト

画面やAPIの待ち時間を超えたため、アプリがDB処理をキャンセルしているケースです。DBだけでなくWeb/APサーバーのログも確認します。

SQLが遅い・ロック待ちしている

実行時間が長いSQLやロック待ちがタイムアウトを誘発します。ロック調査は ORA-00054の記事セッション確認の記事 も参考になります。

ネットワークや接続断と混同している

接続自体が切れる場合は ORA-03113 など別のエラーになることもあります。ORA-01013はまずキャンセル経路を疑います。

最初に確認するポイント

ORA-01013が出たら、いきなりDBパラメータを変更するのではなく、発生条件をメモします。この情報がないと、SQL改善なのか、タイムアウト設定なのか、ロック調査なのかがぼやけます。

  • どの画面・バッチ・SQLで発生したか
  • 何秒後に発生したか
  • 手動で停止した人がいるか
  • 同じSQLをSQL Developerなどで実行すると成功するか
  • 発生時刻にアプリログ・DBログ・ジョブログへ何が出ているか
  • ロック待ちや長時間実行SQLがなかったか
決まった秒数で落ちる時は設定値を疑う
毎回30秒、60秒、120秒、300秒のようなきれいな秒数でORA-01013になる場合、SQLの途中でアプリやミドルウェアがキャンセルしている可能性が高いです。DBのエラーログだけでなく、接続プール、ORM、API、帳票ツール、ジョブ管理ツールのタイムアウト値を確認します。

DB側で確認するSQL

エラー発生中に調査できる場合は、対象セッションが何を待っているかを確認します。ORA-01013が出た後ではセッションやSQLが消えていることもあるため、再現できる環境なら発生中に別セッションから確認するのが理想です。

check-running-session.sql
SELECT
    s.sid,
    s.serial#,
    s.username,
    s.status,
    s.event,
    s.wait_class,
    s.seconds_in_wait,
    s.sql_id,
    s.module,
    s.machine,
    s.program
FROM v$session s
WHERE s.username IS NOT NULL
ORDER BY s.seconds_in_wait DESC;

eventwait_class でロック待ち、I/O待ち、ネットワーク待ちなどを見ます。対象の sql_id が分かる場合は、実行中SQLの内容も確認します。

V$SESSIONが見られない場合
V$SESSIONV$SQL は環境によって権限が必要です。見られない場合は、DBAに発生時刻、接続ユーザー、画面名、バッチ名、SQLの一部を伝えて調査してもらいます。アプリログ側で module やSQL_IDを出している環境なら、DBA側の調査がかなり進めやすくなります。
check-sql-text.sql
SELECT sql_id, child_number, elapsed_time, executions, rows_processed
FROM v$sql
WHERE sql_id = :sql_id;

SELECT sql_text
FROM v$sqltext
WHERE sql_id = :sql_id
ORDER BY piece;

ロックが疑わしい場合は、ブロッキングセッションも確認します。詳しい見方は セッションの確認・強制切断方法 にまとめています。

check-blocking-session.sql
SELECT
    sid,
    serial#,
    username,
    blocking_session,
    event,
    wait_class,
    seconds_in_wait,
    sql_id
FROM v$session
WHERE blocking_session IS NOT NULL;

アプリ側タイムアウトを確認する

アプリ経由でだけORA-01013が出る場合、DBより先にアプリ側の設定を確認します。SQL Developerでは10分で終わるのに画面では60秒で失敗する、という場合は、DBではなく画面/API側が待ちきれずにキャンセルしている可能性があります。

jdbc-query-timeout.java
try (PreparedStatement ps = conn.prepareStatement(sql)) {
    // 例: 60秒を超えたらSQLをキャンセルする
    ps.setQueryTimeout(60);
    try (ResultSet rs = ps.executeQuery()) {
        while (rs.next()) {
            // result handling
        }
    }
}
odpnet-command-timeout.cs
using var cmd = connection.CreateCommand();
cmd.CommandText = sql;
// 例: 60秒を超えたらコマンドをタイムアウトさせる
cmd.CommandTimeout = 60;
using var reader = cmd.ExecuteReader();

タイムアウト値を伸ばすだけで解決したように見えることもありますが、根本原因がSQLの遅さやロック待ちなら再発します。まずはSQLの実行時間、取得件数、実行計画、ロック待ちを確認し、その上で業務上必要な待ち時間を決めます。トランザクション境界やロックの考え方は Oracleトランザクションの記事 も参考になります。

SQLが遅くてキャンセルされる場合

ORA-01013そのものはキャンセルを示しますが、背景にSQL性能問題があることはよくあります。特定SQLだけで繰り返す場合は、キャンセルされたSQLを特定して、実行計画と条件を確認します。

  • 検索条件に必要な索引があるか
  • 不要に広い期間・全件を検索していないか
  • 画面表示に不要な列や行を取得していないか
  • 集計・ソート・結合でTEMPを大量に使っていないか
  • ロック待ちをSQLの遅さと誤認していないか
explain-plan.sql
EXPLAIN PLAN FOR
SELECT /* target sql */ *
FROM orders
WHERE order_date >= DATE '2026-01-01';

SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY);

本番で長時間SQLを調べる場合は、権限や環境に応じて V$SQL、AWR、ASH、SQL Monitor などを使います。ORA-01013だけを見てSQLを直すのではなく、「キャンセルされるほど遅くなっている理由」を確認するのが重要です。

DB停止時に出るORA-01013は別扱い

通常のSQL実行中に出るORA-01013は、手動キャンセルやアプリ側タイムアウトを疑います。ただし、SHUTDOWN 実行中にORA-01013が出た場合は少し意味が変わります。OracleのSQL*Plusドキュメントでは、停止処理で待機対象が制限時間内に完了しない場合にもORA-01013が表示されることが説明されています。

DB停止中のORA-01013では、通常SQLのタイムアウト調査ではなく、停止処理がどこで待っているか、接続ユーザーやトランザクションが残っていないかを確認します。安易に何度も停止コマンドを中断するのではなく、運用手順に沿って再実行や SHUTDOWN ABORT の要否を判断します。

再実行してよいか判断する

SELECTのキャンセルなら再実行しやすいですが、INSERT/UPDATE/DELETEやバッチ処理では注意が必要です。キャンセル時点でどこまで処理されたか、コミット済みか、アプリ側でリトライされていないかを確認します。

参照SQL

基本的には再実行しやすいです。ただし検索条件や取得件数が重い場合は、先に条件を絞ります。

更新SQL

トランザクションがロールバックされたか、途中でコミットされていないかを確認します。二重更新に注意します。

バッチ処理

処理済みフラグ、再実行キー、ログテーブル、コミット単位を確認してから再実行します。

外部連携

相手先へ送信済みか、再送可能か、冪等性があるかを確認します。DBだけ見て判断しない方が安全です。

似たエラーとの違い

ORA-01013はキャンセル系のメッセージです。バインド変数やカーソル系のORA-010xxとは原因が違うため、同じ番号帯でも切り分け方を分けます。

ORA-01013

実行中の処理がキャンセルされた。手動停止、アプリタイムアウト、ジョブ制限時間などを確認します。

ORA-01006

SQLに存在しないバインド変数を渡している可能性があります。詳しくは ORA-01006の記事 を参照してください。

ORA-01008

SQL内のバインド変数に値が不足しています。詳しくは ORA-01008の記事 を参照してください。

ORA-01036

バインド変数名や番号、バインドできない場所の指定が不正です。詳しくは ORA-01036の記事 を参照してください。

ORA-01001

カーソルの状態が不正です。カーソルのクローズ、再利用、FETCH順序を確認します。詳しくは ORA-01001の記事 を参照してください。

対応手順まとめ

  1. 手動キャンセルか、アプリ・バッチの自動キャンセルかを確認する
  2. 何秒後に発生するかを確認する
  3. SQL Developerなどで同じSQLを単体実行して再現するか確認する
  4. 発生中に V$SESSION で待機イベント、SQL_ID、ロック待ちを確認する
  5. アプリ側のクエリタイムアウト、HTTPタイムアウト、ジョブ制限時間を確認する
  6. SQLが遅い場合は実行計画、索引、取得件数、ロックを見直す
  7. 更新処理やバッチの場合は、再実行前にコミット状況と二重実行リスクを確認する

ORA-01013は、メッセージだけで見ると抽象的ですが、原因の多くは「キャンセルした主体」を追うことで整理できます。単発なら大きな問題ではないこともありますが、同じ画面やバッチで繰り返す場合は、SQL性能、ロック、アプリ側タイムアウトのどれかに原因がある可能性が高いです。

まずは発生秒数と実行経路を確認し、DB側の待機状況とアプリ側のタイムアウト設定を突き合わせてください。その上で、SQLを直すのか、タイムアウト値を見直すのか、処理方式を分けるのかを判断すると、場当たり的な対応になりにくくなります。

よくある質問

ORA-01013はDB障害ですか?

単発で、利用者が停止ボタンや Ctrl+C で止めた場合は、DB障害ではないことが多いです。一方で、同じ処理で繰り返す場合は、SQLの遅さ、ロック待ち、アプリ側タイムアウトを調査します。

ORA-01013が出たSQLは再実行してよいですか?

SELECTなら再実行しやすいですが、更新処理やバッチでは注意が必要です。コミット済みの範囲、処理済みフラグ、外部連携の送信状況を確認してから再実行します。

SQL Developerでは成功するのにアプリでは失敗するのはなぜですか?

アプリ側のクエリタイムアウトやHTTPタイムアウトの方が短い可能性があります。同じSQLでも、実行経路が違うと待てる時間や取得件数、バインド値が変わることがあります。

タイムアウト値を伸ばせば解決ですか?

一時的な回避にはなりますが、根本原因がSQL性能やロック待ちなら再発します。まず発生秒数、実行計画、ロック待ち、取得件数を確認し、必要な場合だけタイムアウト値を調整します。

参考