自律型トランザクション Oracle PL / SQLの

⚡ スマートサマリー

取引管理ステートメント Oracle PL/SQLでは、COMMIT、ROLLBACK、SAVEPOINTといったメソッドによって、保留中のDML変更を保存するか破棄するかが決定されます。自律トランザクションは、メイントランザクションとは独立してコミットまたはロールバックを行うサブプログラムとして実行されます。

  • 💾 専念: 保留中のすべてのDML変更を確定し、トランザクションを終了し、ロックを解除し、すべてのセーブポイントを消去します。
  • ↩️ ロールバック: 保留中の変更を取り消します。トランザクション全体、または指定した保存ポイントまで戻します。
  • 📌 セーブポイント: トランザクション内の特定の時点をマークすることで、後続の ROLLBACK TO で作業の一部のみを取り消すことができるようにします。
  • 🔀 自律的な取引: PRAGMA AUTONOMOUS_TRANSACTION ディレクティブを使用すると、サブプログラムが独自にコミットまたはロールバックを実行できます。
  • 🧾 使用事例: 自律的なトランザクションは、メインの処理がロールバックされた場合でも保持されなければならない監査およびエラーログ記録に適しています。
  • 🤖 AI 支援: GitHub CopilotなどのAIアシスタントは、COMMIT、ROLLBACK、PRAGMAブロックを作成し、不足しているコミットを指摘します。

自律型トランザクション Oracle COMMITとROLLBACKを使用したPL/SQL

PL/SQL の TCL ステートメントとは何ですか?

TCLはトランザクション制御ステートメントの略です。これらのステートメントは、保留中のトランザクションを保存するか、保留中のトランザクションをロールバックします。トランザクションが保存されない限り、トランザクションによって行われた変更は実行されないため、TCLは重要な役割を果たします。 DMLステートメント データベースに永続的に保存されることはありません。以下は、さまざまな TCL ステートメントです。 PL / SQLの.

ステートメント 詳細説明
コミット 保留中のすべての取引を保存します。
ロールバック 保留中のトランザクションをすべて破棄します。
セーブポイント トランザクション内に、後でロールバックを実行できるポイントを作成します。
にロールバック 指定されたセーブポイントまでの保留中のトランザクションをすべて破棄します。

以下のシナリオでは、取引が完了します。

  • 上記のいずれかのステートメントが発行された場合(SAVEPOINTを除く)。
  • DDLステートメントが発行されるとき(DDLは自動コミットステートメントです)。
  • DCLステートメントが発行される場合(DCLは自動コミットステートメントです)。

SAVEPOINTとROLLBACKを使用して

上記の表は、SAVEPOINT と ROLLBACK TO を紹介するもので、これらを組み合わせることでトランザクションを部分的に制御できます。SAVEPOINT は、現在のトランザクション内の特定のポイントをマークします。そのセーブポイントに対して後から ROLLBACK TO を実行すると、それ以降に行われたすべての変更が取り消されます。ping それ以前に行われた作業はそのまま残された。

これは、長時間のトランザクションが複数の処理を実行する場合に役立ちます。 SQL 処理手順が複数あり、最後のステップのみが失敗した場合、トランザクション全体を破棄するのではなく、最後に正常に保存された時点までロールバックして処理を続行できます。

構文:

SAVEPOINT <savepoint_name>;
   -- one or more DML statements
ROLLBACK TO <savepoint_name>;

セーブポイントについて覚えておくべき重要なポイント:

  • セーブポイントは現在のトランザクション内でのみ存在し、コミットまたは完全なロールバックを行うと、すべてのセーブポイントが消去されます。
  • セーブポイントまでロールバックすると、それ以降に作成されたセーブポイントはすべて消去されますが、ロールバック先のセーブポイント自体は保持されます。
  • ROLLBACK TO を実行してもトランザクションは終了しません。セーブポイントより前に行われた変更は、COMMIT または ROLLBACK を実行するまで保留状態のままになります。
  • セーブポイント名を再利用した場合、新しいSAVEPOINTによってマーカーが後の位置に移動します。

ROLLBACK TO はトランザクションを開いたままにするため、最後に残りの変更を COMMIT するか、完全な ROLLBACK で破棄するかを決定できます。

自律型トランザクションとは

PL/SQLでは、データに対して行われるすべての変更をトランザクションと呼びます。トランザクションは、保存または破棄処理が適用された時点で完了とみなされます。保存または破棄処理が行われない場合、トランザクションは完了とはみなされず、データに対して行われた変更はサーバー上に永続的に保存されません。

デフォルトでは、PL/SQL はセッション中のすべての変更を単一のトランザクションとして扱い、そのトランザクションを保存または破棄すると、セッション内の保留中のすべての変更に影響します。自律トランザクションを使用すると、開発者は別のトランザクションで変更を行い、メインセッションのトランザクションに影響を与えることなく、その特定のトランザクションを保存または破棄することができます。

  • 自律的なトランザクションは、サブプログラムレベルで指定できます。
  • 何かを作るには サブプログラム 別のトランザクションで作業する場合は、そのブロックの宣言セクションにキーワード PRAGMA AUTONOMOUS_TRANSACTION を指定する必要があります。
  • これはコンパイラに対し、これを独立したトランザクションとして扱うよう指示するものであり、このブロック内での保存や破棄はメインのトランザクションには反映されません。
  • この自律トランザクションを終了してメインのトランザクションに戻る前に、COMMITまたはROLLBACKを発行することが必須です。なぜなら、同時にアクティブにできるトランザクションは1つだけだからです。
  • したがって、自律的なトランザクションが開始されたら、メインのトランザクションに制御を戻す前に、そのトランザクションを保存して完了させる必要があります。

構文:

DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
.
BEGIN
<execution_part>
[COMMIT|ROLLBACK]
END;
/

上記の構文では、ブロックは独立したトランザクションとして扱われています。

例1: この例では、自律的な取引がどのように機能するのかを理解していきます。

以下のスクリーンショットは、この自律トランザクションの例とその出力を示しています。 Oracle.

メイントランザクションがロールバックしている間にネストされたブロックをコミットする自律トランザクションの例 Oracle PL / SQLの

DECLARE
   l_salary   NUMBER;
   PROCEDURE nested_block IS
   PRAGMA autonomous_transaction;
    BEGIN
     UPDATE emp
       SET salary = salary + 15000
       WHERE emp_no = 1002;
   COMMIT;
   END;
BEGIN
   SELECT salary INTO l_salary FROM emp WHERE emp_no = 1001;
   dbms_output.put_line('Before Salary of 1001 is'|| l_salary);
   SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002;
   dbms_output.put_line('Before Salary of 1002 is'|| l_salary);    
   UPDATE emp 
   SET salary = salary + 5000 
   WHERE emp_no = 1001;

nested_block;
ROLLBACK;

 SELECT salary INTO  l_salary FROM emp WHERE emp_no = 1001;
 dbms_output.put_line('After Salary of 1001 is'|| l_salary);
 SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002;
 dbms_output.put_line('After Salary of 1002 is '|| l_salary);
end;

出力

Before:Salary of 1001 is 15000 
Before:Salary of 1002 is 10000 
After:Salary of 1001 is 15000 
After:Salary of 1002 is 25000

Code 説明:

  • Code 2行目: l_salaryをNUMBER型として宣言します。
  • Code 3行目: nested_block プロシージャを宣言します。
  • Code 4行目: ネストされたブロックプロシージャをAUTONOMOUS_TRANSACTIONにする。
  • Code 7行目~9行目: 従業員番号 1002 の給与を 15000 増加します。
  • Code 10行目: 自律的な取引を実行します。
  • Code 13行目~16行目: 変更前の従業員1001番と1002番の給与明細を印刷します。
  • Code 17行目~19行目: 従業員番号 1001 の給与を 5000 増加します。
  • Code 20行目: nested_blockプロシージャを呼び出しています。
  • Code 21行目: メイントランザクションを破棄します。
  • Code 22行目~25行目: 変更後の従業員1001番と1002番の給与明細を印刷します。

従業員番号1001の給与増額は、メインの取引が破棄されたため反映されていません。従業員番号1002の給与増額は、そのブロックが別の取引として作成され、最後に保存されたため反映されています。

したがって、メイントランザクションでの保存または破棄に関係なく、自律トランザクションでの変更はメイントランザクションに影響を与えることなく保存されます。

自律型トランザクションを使用するタイミング

自律トランザクションは強力な機能であるため、いつ使用すべきかを理解することが重要です。自律トランザクションは、メインのトランザクションとは独立して成功または失敗しなければならない処理に限定し、コアとなるビジネスロジックには使用しないでください。一般的な使用例は次のとおりです。

  • 監査ログ: 機密データを誰が、いつ、変更したのか、変更前の値と変更後の値を記録しておくことで、メインのトランザクションがロールバックされた場合でもログが保持されます。
  • エラーロギング: エラーレコードを 例外 ハンドラーを呼び出し、それをコミットすることで、失敗したトランザクションは破棄される一方で、診断の詳細は保持されます。
  • カウンターと統計情報: 呼び出し元の結果に関わらず維持される必要のある使用回数カウンターまたはヒット数を進めます。
  • トリガー内での COMMIT: トリガーは直接 COMMIT を発行することはできません。自律トランザクションのみが、COMMIT を発行するための唯一のサポートされている方法です。

メイントランザクションと同じ運命を共有すべき通常の更新処理には、自律トランザクションの使用を避けてください。自律トランザクションを過剰に使用すると、データが独立したコミットの背後に隠蔽され、デバッグが困難になる可能性があります。原則として、すべての自律ブロックは明示的な COMMIT または ROLLBACK で終了する必要があります。

自律型取引と通常取引

通常の(メイン)トランザクションと自律トランザクションの違いは、範囲と独立性にあります。以下の表で両者を比較します。

側面 通常取引 自律型トランザクション
対象領域 1つのセッショントランザクションを共有します 別個の子トランザクションとして実行されます
コミット/ロールバック効果 保留中のすべてのセッション変更に影響します 自律ブロックのみに影響します
宣言 デフォルトの動作 宣言セクションの PRAGMA AUTONOMOUS_TRANSACTION
親ロールバックの影響 変更が失われる 自主的な変更が継続されます
典型的な使用 コアビジネスロジック 監査およびエラーログ

通常の ネストされたブロック変更内容が常に周囲のトランザクションの結果を共有するメインブロックとは異なり、自律ブロックはそれ自体で独立しています。この違いを理解することで、ブロックを独立させるべき場合と、メイントランザクションの結果を共有させるべき場合を判断するのに役立ちます。

よくあるご質問

Oracle ORA-06519 エラーが発生し、自律処理がロールバックされます。自律トランザクションは、メイン トランザクションに制御が戻る前に、明示的な COMMIT または ROLLBACK で終了する必要があります。これは、同時に実行できるトランザクションが 1 つだけであるためです。

直接的にはできません。通常のトリガーは COMMIT や ROLLBACK を発行できません。トリガー、またはトリガーが呼び出すプロシージャを PRAGMA AUTONOMOUS_TRANSACTION で宣言すると、トリガーを起動したステートメントとは独立して、独自の変更をコミットできるようになります。

いいえ。親トランザクションが一時停止されると、自律トランザクションは独立して実行され、親トランザクションの未コミットの変更を参照することはできません。データベースに既にコミットされたデータのみを参照するため、親トランザクションのロックを待機するとデッドロックが発生する可能性があります。

はい。CREATE、ALTER、DROPなどのすべてのDDLステートメントは、実行前後に暗黙的にCOMMITを発行します。セッション内の保留中のDMLはすべて自動的にコミットされるため、DDLステートメントは後からロールバックすることはできません。

自律的なブロックは別のブロックを呼び出すことができ、それぞれが独自のコミットまたはロールバックを管理します。 Oracle TRANSACTIONS初期化パラメータによって同時にアクティブにできるトランザクションの数を制限するため、自律ブロックの非常に深いネストは失敗する可能性があります。

いいえ。COMMITは変更を永続化し、ロックを解除し、セーブポイントを消去するため、ROLLBACKでは元に戻すことはできません。コミットしたデータを元に戻すには、新しいDMLを実行する必要があります。コミットする前に、部分的な元に戻すにはSAVEPOINTとROLLBACK TOを使用してください。

Yes. GitHubコパイロット コメントから COMMIT および ROLLBACK ロジック、SAVEPOINT ブロック、および PRAGMA AUTONOMOUS_TRANSACTION プロシージャのドラフトを作成します。 Revコミットの配置とエラー処理を確認してください。誤った場所にコミットすると、トランザクションの境界が破損する可能性があります。

AIアシスタントは、COMMITおよびROLLBACKステートメントの欠落や配置ミス、ループ内のコミット、閉じられていない自律ブロックなどをプロシージャ内でスキャンします。この機械学習によるレビューは、トランザクションのバグを検出し、コードが本番環境にデプロイされる前に、より安全な境界を提案します。