自律型トランザクション Oracle PL / SQLの
⚡ スマートサマリー
取引管理ステートメント Oracle PL/SQLでは、COMMIT、ROLLBACK、SAVEPOINTといったメソッドによって、保留中のDML変更を保存するか破棄するかが決定されます。自律トランザクションは、メイントランザクションとは独立してコミットまたはロールバックを行うサブプログラムとして実行されます。
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.
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 |
| 親ロールバックの影響 | 変更が失われる | 自主的な変更が継続されます |
| 典型的な使用 | コアビジネスロジック | 監査およびエラーログ |
通常の ネストされたブロック変更内容が常に周囲のトランザクションの結果を共有するメインブロックとは異なり、自律ブロックはそれ自体で独立しています。この違いを理解することで、ブロックを独立させるべき場合と、メイントランザクションの結果を共有させるべき場合を判断するのに役立ちます。


