【PL/SQL】AUTONOMOUS TRANSACTIONで独立した処理を行う方法

【PL/SQL】AUTONOMOUS TRANSACTIONで独立した処理を行う方法 PL/SQL

PL/SQLのトランザクションは通常1セッション内で共有され、COMMITやROLLBACKは全体に影響します。しかし「本体トランザクションとは独立してログを書き込みたい」「監査やエラーログだけは確定させたい」といった場面では、AUTONOMOUS TRANSACTION(自律トランザクション)が役立ちます。これは呼び出し元とは別の独立したトランザクションを開始し、呼び出し終了時に制御が戻る特殊な仕組みです。ここでは基本構文、ログ記録の実例、ネストと制限、注意点まで解説します。

基本構文と特徴

自律トランザクションはPRAGMA AUTONOMOUS_TRANSACTIONをプロシージャやファンクション、トリガー、匿名ブロックに宣言することで有効になります。このブロック内では独立したトランザクションが開始され、COMMITまたはROLLBACKが必須です。

CREATE OR REPLACE PROCEDURE write_log(p_msg VARCHAR2) IS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO audit_log(log_time, message)
    VALUES (SYSTIMESTAMP, p_msg);
  COMMIT; -- 呼び出し元に影響しない
END;
/

呼び出し元がROLLBACKしても、write_log内のINSERTは確定したまま残ります。

典型的な利用例:エラーログの記録

エラー発生時にロールバックされても監査やログだけは残したい場合、AUTONOMOUS TRANSACTIONが不可欠です。

BEGIN
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    write_log('transfer failed: ' || SQLERRM); -- 自律トランザクションで記録
    ROLLBACK;
    RAISE;
END;
/

これにより本体はROLLBACKされますが、audit_logテーブルには失敗記録が確定されます。

匿名ブロックでの利用

プロシージャやトリガーだけでなく、匿名PL/SQLブロックでも宣言できます。

DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO temp_log VALUES(SYSTIMESTAMP,'check');
  COMMIT;
END;
/

トリガーでの利用

監査用トリガーで「必ず記録を残す」設計にする場合も有効です。

CREATE OR REPLACE TRIGGER trg_audit
AFTER UPDATE ON employees
FOR EACH ROW
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO emp_audit(emp_id, old_sal, new_sal, upd_time)
  VALUES (:OLD.id, :OLD.salary, :NEW.salary, SYSTIMESTAMP);
  COMMIT;
END;
/

この場合、更新がROLLBACKされても監査レコードは残ります。

制約と注意点

  • 自律トランザクション内では必ずCOMMITまたはROLLBACKが必要です。忘れるとORA-06519エラーになります。
  • 呼び出し元とのリソース共有は行えません。ロックやカーソル、変数は独立しています。
  • 本体トランザクションが失敗してROLLBACKされた場合でも、自律トランザクションで確定した内容は戻りません。
  • デッドロックを避けるため、呼び出し元と同じ表に対して更新を行うのは推奨されません。

ネストの扱い

自律トランザクションの中からさらに別の自律トランザクションを呼ぶことも可能ですが、いずれも完全に独立しています。呼び出し階層によってコミットの伝播はしないため、論理的な整合性を壊さないよう設計する必要があります。

ベストプラクティス

1. 主用途は監査・ログ・メトリクス記録に限定する
2. 本体と同じ業務データの変更には使わない
3. COMMIT/ROLLBACKを必ず明示し、抜け漏れを防ぐ
4. 適切なエラーハンドリングとログ設計をセットで導入する

まとめ

AUTONOMOUS TRANSACTIONは、呼び出し元とは独立して確定処理を行える強力な仕組みです。エラーログや監査のように「失敗しても必ず残す」処理に最適です。ただし、本体トランザクションと切り離されるため、一貫性を崩さない範囲で限定的に利用することが正しい使い方となります。