ヘッダーをスキップ

Oracle Database 概要
11gリリース1(11.1)

E05765-03
目次
目次
索引
索引

戻る 次へ

4 トランザクションの管理

この章では、トランザクションを定義し、トランザクションを使用して作業を管理する方法について説明します。

この章の内容は、次のとおりです。

トランザクションの概要

トランザクションは、1つ以上のSQL文を含む論理作業単位です。トランザクションはアトミック(基本)な単位です。つまり、トランザクション内のすべてのSQL文は、すべてコミット(データベースに適用)されるか、すべてロールバック(データベースから取消し)されるかのどちらかになります。

トランザクションは、最初の実行可能なSQL文から開始します。トランザクションは、COMMIT文またはROLLBACK文を使用して明示的に、またはDDL文を発行して暗黙的にコミットまたはロールバックされた時点で終了します。

トランザクションの概念を具体的に説明するため、銀行業務データベースについて考えてみます。銀行の顧客が普通預金口座から当座預金口座へ預金を振り替える場合、トランザクションは次の3つの別々の操作で構成されます。

Oracle Databaseでは、2つの状況が考慮されます。3つのSQL文がすべて実行されて、口座の差引残高の帳尻が合えば、トランザクションの結果をデータベースに適用できます。ただし、預金額の不足、口座番号が無効、またはハードウェア障害などの問題が原因で、トランザクション内の1つまたは2つの文が完了しない場合は、すべての口座の差引残高が正しく維持されるようにトランザクション全体をロールバックする必要があります。

図4-1に銀行のトランザクションの例を示します。

図4-1    銀行のトランザクション


画像の説明

この項の内容は、次のとおりです。

文の実行とトランザクションの制御

正常に実行されるSQL文とコミットされるトランザクションとは異なります。正常に実行されるとは、単一の文が次の条件を満たしたことを意味します。

ただし、その文が含まれているトランザクションがコミットされるまでは、トランザクションをロールバックしてその文のすべての変更を取り消せます。正常に実行される(成功する)という表現は、トランザクションではなく、文に対して使用します。

コミットとは、ユーザーが明示的または暗黙的に、このトランザクションの変更内容を確定するように要求することを意味します。明示的な要求は、ユーザーがCOMMIT文を発行すると発生します。暗黙的な要求は、アプリケーションの正常終了後またはデータ定義言語(DDL)操作の完了後に発生します。トランザクションがコミットされて初めて、トランザクションのSQL文による変更内容が確定され、他のユーザーがこれらの変更を参照できるようになります。トランザクションのコミット後に発行された問合せでは、コミットされた変更を参照できます。

トランザクションを開始する前に、SET TRANSACTION ... NAME文を使用して、トランザクションに名前を付けることができます。名前を付けることで、長時間実行のトランザクションの監視およびインダウト分散トランザクションの解決が容易になります。

関連項目

「トランザクションの命名」 

文レベルのロールバック

実行中にSQL文のエラーが発生すると、その文のすべての効果はロールバックされます。ロールバックの効果は、その文がまったく実行されなかった場合と同じ状態にすることです。この操作が文レベルのロールバックです。

SQL文の実行中にエラーが検出されると、文レベルのロールバックが発生します。この種のエラーの一例として、主キーに重複値を挿入しようとした場合があります。1つのデッドロック(同じデータに関する競合)に単一SQL文が複数関係している場合も、文レベルのロールバックが発生します。解析中に構文エラーなどのエラーが検出された場合は、まだSQL文は実行されていないため、文レベルのロールバックは発生しません。

SQL文でエラーが発生した場合は、SQLでの実行予定の作業のみが影響を受けます。現行のトランザクションにおけるこれまでの作業に影響を及ぼすことはありません。文がDDL文の場合、その文の直前に実行された暗黙的コミットは取り消されません。


注意

ユーザーは、ロールバック文の中で暗黙的セーブポイントを直接参照できません。 


関連項目

「デッドロック」 

再開可能領域割当て

Oracle Databaseでは、領域割当てエラーが発生した場合、大規模なデータベース操作の実行を一時停止および再開することが可能です。このため、Oracleデータベース・サーバーからユーザーにエラーを戻すかわりに、管理者は対処措置を取ることができます。エラー条件が修正されると、一時停止中の操作が自動的に再開されます。

再開可能モードで文が実行されるのは、クライアントがALTER SESSION文を使用して、明示的にセッションの再開可能セマンティクスを使用可能にした場合のみです。

次のような場合、再開可能領域割当ては一時停止されます。

非再開可能領域割当ての場合、これらの条件ではエラーが発生し、文がロールバックされます。

文を一時停止すると、トランザクションが自動的に一時停止されます。このため、トランザクションのすべてのリソースが、一時停止文および再開文を介して保持されます。

エラー条件が(たとえば、ユーザーの介入、または他の問合せによりソート領域が解放された結果として)消滅すると、一時停止中の文が自動的に実行を再開します。

関連項目

再開可能領域割当てを使用可能にする方法、修正可能な条件および再開可能にすることが可能な文の詳細は、『Oracle Database管理者ガイド』を参照してください。 

トランザクション管理の概要

Oracle Databaseでのトランザクションは、最初の実行可能SQL文が検出された時点で開始されます。実行可能SQL文は、DML文やDDL文など、インスタンスへのコールを生成するSQL文です。

トランザクションが開始されると、Oracle Databaseはそのトランザクションを使用可能なUNDO表領域に割り当てて、新しいトランザクションのロールバック・エントリを記録します。

トランザクションは、次のいずれかの状況が発生すると終了します。

1つのトランザクションが終了すると、次の実行可能SQL文によって次のトランザクションが自動的に開始されます。

この項の内容は、次のとおりです。

トランザクションのコミット

トランザクションをコミットするとは、トランザクション内のSQL文によって実行された変更を確定する操作のことです。

データを修正したトランザクションがコミットされる前に、次の処理が完了しています。

トランザクションをコミットすると、次の処理が実行されます。

  1. 対応付けられたUNDO表領域の内部トランザクション表にトランザクションがコミットされたことが記録され、トランザクションの対応する一意のシステム変更番号(SCN)が割り当てられ、その表に記録されます。

  2. ログ・ライター・プロセス(LGWR)は、SGAのREDOログ・バッファ内のREDOログ・エントリをREDOログ・ファイルに書き込みます。LGWRは、トランザクションのSCNもREDOログ・ファイルに書き込みます。これが、トランザクションのコミットを構成するアトミック・イベントです。

  3. Oracle Databaseにより、行と表に対して保持されているロックが解放されます。

  4. Oracle Databaseにより、トランザクションに完了のマークが付けられます。


    注意

    デフォルトの動作では、LGWRによりREDOがオンラインREDOログ・ファイルに同時に書き込まれ、トランザクションはREDOがディスクに移動するまで待機してから、コミットをユーザーに戻します。ただし、アプリケーション開発者は、トランザクションのコミット待機時間を短縮するために、REDOが非同期に書き込まれ、REDOがディスクに移動するまでトランザクションが待機する必要がないよう指定できます。  


    関連項目

     

トランザクションのロールバック

ロールバックとは、コミットされていないトランザクション内のSQL文によって実行されたデータ変更を取り消すことを意味します。Oracle Databaseは、UNDO表領域(またはロールバック・セグメント)を使用して古い値を格納します。REDOログには、変更の履歴が記録されます。

Oracle Databaseでは、コミットされていないトランザクション全体をロールバックできます。また、コミットされていないトランザクションの後半部分をセーブポイントと呼ばれるマーカーまでロールバックすることもできます。

次のすべてのタイプのロールバックで、同じ手順が使用されます。

セーブポイントを参照しないで、トランザクション全体をロールバックした場合、次の処理が実行されます。

  1. Oracle Databaseにより、トランザクションのすべてのSQL文によるすべての変更が、対応するUNDO表領域を使用して取り消されます。

  2. Oracle Databaseにより、そのトランザクションのすべてのデータ・ロックが解放されます。

  3. トランザクションが終了します。

    関連項目

     

トランザクションのセーブポイント

トランザクションのコンテキスト内で、セーブポイントと呼ばれる中間マーカーを宣言できます。セーブポイントは、ロング・トランザクションをいくつかの小さい部分に分割します。

セーブポイントを使用すると、ロング・トランザクション内の任意のポイントで作業に任意にマークを設定できます。これにより、そのトランザクション内の宣言されたセーブポイントからトランザクション内の現時点までの間に実行された作業を、後でロールバックできるようになります。たとえば、大規模で複雑な一連の更新のどこにでもセーブポイントを設定できるため、エラーが発生してもすべての文を再発行する必要はありません。

セーブポイントは、アプリケーション・プログラム内でも使用できます。プロシージャにいくつかのファンクションが含まれている場合は、それぞれのファンクションの開始前にセーブポイントを作成できます。そうすると、あるファンクションが失敗しても、そのファンクション開始前の状態にデータを復帰し、パラメータを修正してから再実行したり、リカバリ作業を実行するのが容易になります。

セーブポイントまでロールバックすると、Oracle Databaseはロールバック文が取得したデータ・ロックを解放します。以前にロックされていたリソースを待機していた他のトランザクションは、続行できます。以前にロックされていた行を更新しようとする他のトランザクションは、それらの行を更新できます。

トランザクションをセーブポイントまでロールバックした場合、次の処理が実行されます。

  1. Oracle Databaseにより、セーブポイントの後に実行された文のみがロールバックされます。

  2. Oracle Databaseでは、指定されたセーブポイントは保存されますが、そのセーブポイントより後に設定されたセーブポイントはすべて失われます。

  3. Oracle Databaseにより、そのセーブポイントの後に取得された表と行のすべてのロックが解放されますが、そのセーブポイントより前に取得されたすべてのデータ・ロックは保持されます。

トランザクションはアクティブであり、継続できます。

セッションが待機中の場合は、トランザクションをセーブポイントまでロールバックした場合でも行のロックは解放されません。トランザクションがロックを取得できない場合に異常終了しないように、UPDATEまたはDELETE文を発行する前に、FOR UPDATE ... NOWAITを使用します。(これは、ロールバックしたセーブポイントの前に取得されたロックを参照します。セーブポイントの後に実行された文は完全にロールバックされているため、このセーブポイントの後に取得された行ロックが解放されます。)

トランザクションの命名

トランザクションの名前には、簡単で覚えやすいテキスト文字列を使用できます。この名前は、トランザクションの目的を連想できるように命名します。分散トランザクションのコミット・コメントをトランザクションの名前に置換することには、次の利点があります。

この項の内容は、次のとおりです。

トランザクションの命名方法

トランザクションを開始する前に、SET TRANSACTION ... NAME文を使用して、トランザクションに名前を付けます。

トランザクションに名前を付けるときは、IDと対応付けます。トランザクション名は一意の必要がないので、所有者が複数のトランザクションに同じトランザクション名を付けることも可能です。トランザクションを識別できるように任意の名前を付けることができます。

コミット・コメント

以前のリリースでは、コミット・コメントを使用してコメントをトランザクションに対応付けることができました。ただし、コメントをトランザクションに対応付けられるのは、トランザクションがコミットされているときのみです。

下位互換性を維持するため、コミット・コメントは引き続きサポートされます。ただし、トランザクション名を使用することをお薦めします。コミット・コメントは名前付きトランザクションでは処理されません。


注意

将来のリリースでは、コミット・コメントは使用できなくなります。 


関連項目

  • 分散トランザクションの詳細は、『Oracle Database管理者ガイド』を参照してください。

  • トランザクション命名構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

 

2フェーズ・コミット・メカニズム

分散データベースでは、Oracle Databaseはネットワーク全体でトランザクション制御を調整し、ネットワーク障害やシステム障害が発生した場合にもデータ整合性が保たれるようにする必要があります。

分散トランザクションとは、分散データベースにおいて複数の異なるノード上でデータを更新する、1つ以上の文を含むトランザクションのことです。

2フェーズ・コミット・メカニズムは、分散トランザクションに関係するすべてのデータベース・サーバーが、そのトランザクション内の文のすべてをコミットするか、またはすべてを取り消すかのどちらか一方のみになるように保証するものです。また、2フェーズ・コミット・メカニズムは、整合性制約、リモート・プロシージャ・コールおよびトリガーによって実行される暗黙的DML操作も保護します。

Oracle Databaseの2フェーズ・コミット・メカニズムは、分散トランザクションを発行するユーザーからはまったく意識されません。事実、ユーザーは、トランザクションが分散していることも認識する必要はありません。トランザクションの終了を示すCOMMIT文は、自動的に2フェーズ・コミット・メカニズムをトリガーしてトランザクションをコミットします。データベース・アプリケーション本体に分散トランザクションを含めるのに、コーディングや複雑な構文の記述は必要ありません。

リカバラ(RECO)・バックグラウンド・プロセスは、インダウト分散トランザクション(システム障害やネットワーク障害によってコミットが中断された分散トランザクション)の結果を自動的に解決します。障害が修復され、通信が再確立された後、各ローカルのOracleデータベースのRECOプロセスが、関係するすべてのノード上でインダウト分散トランザクションを自動的にコミットするか、またはロールバックします。

長時間にわたる障害が発生した場合、Oracle Databaseでは、各ローカル管理者が障害によって発生したインダウト分散トランザクションを手動でコミットまたは取り消すことができます。このオプションによって、ローカル・データベース管理者は、長時間にわたる障害の結果として無期限にロックされる可能性のあるリソースを解放できます。

あるデータベースを過去のある時点までリカバリする必要がある場合、Oracle Databaseのリカバリ機能を使用すると、他のサイトのデータベース管理者は、自分のデータベースも過去のその同じ時点に戻すことができます。この操作により、グローバル・データベースは一貫した状態に保たれます。

関連項目

『Oracle Database Heterogeneous Connectivity管理者ガイド』 

自律型トランザクションの概要

自律型トランザクションは、他のトランザクションからコールできる、独立したトランザクションです。自律型トランザクションにより、コール側トランザクションのコンテキストから離れてなんらかのSQL操作を実行し、その操作をコミットまたは取り消してから、コール側トランザクションのコンテキストに戻って引き続き実行できます。

起動後の自律型トランザクションは、コール側のメイン・トランザクションの影響をまったく受けません。メイン・トランザクションによって加えられたがコミットされていない変更は取り扱わず、ロックやリソースをメイン・トランザクションと共有することもありません。自律型トランザクションによって加えられた変更は、自律型トランザクションのコミット時に他のトランザクションから見えるようになります。

自律型トランザクションは、相互にコールし合うことができます。自律型トランザクションをコールできるレベル数には、リソース制限以外の制限はありません。

自律型トランザクションとコール側トランザクションの間で、デッドロックが発生することがあります。Oracle Databaseは、この種のデッドロックを検出するとエラーを戻します。アプリケーション開発者は、デッドロック状況を回避する責任があります。

自律型トランザクションは、トランザクションのロギングや再試行カウンタなど、コール側トランザクションでコミットまたはロールバックするかどうかに関係なく、独立して実行する必要があるアクションを実装する場合に便利です。

自律型PL/SQLブロック

PL/SQLブロックから自律型トランザクションをコールできます。プラグマAUTONOMOUS_TRANSACTIONを使用してください。プラグマは、コンパイラ・ディレクティブです。次の種類のPL/SQLブロックを、自律型として宣言できます。

自律型PL/SQLブロックに入ると、コール元のトランザクション・コンテキストは中断されます。この操作により、このブロック(または、そこからコールされる他のブロック)で実行されるSQL操作は、コール元のトランザクション・コンテキストの状態に依存も影響もしないことが保証されます。

自律型ブロックが他の自律型ブロックまたはそれ自身を起動する場合、コールされたブロックが、コール側ブロックとトランザクション・コンテキストを共有することはありません。ただし、自律型ブロックが自律型でないブロック(つまり、自律型として宣言されていないブロック)を起動する場合、コールされたブロックはコール側の自律型ブロックのトランザクション・コンテキストを継承します。

自律型ブロック内のトランザクション制御文

自律型PL/SQLブロック内のトランザクション制御文は、現在アクティブになっている自律型トランザクションにのみ適用されます。この種の文の例は、次のとおりです。

SET TRANSACTION 
COMMIT 
ROLLBACK 
SAVEPOINT 
ROLLBACK TO SAVEPOINT 

同様に、メイン・トランザクション内のトランザクション制御文は、そのトランザクションにのみ適用され、コールされる自律型トランザクションには適用されません。たとえば、メイン・トランザクションを自律型トランザクションの開始前までロールバックしても、自律型トランザクションは取り消されません。

関連項目

『Oracle Database PL/SQL言語リファレンス』 


戻る 次へ
Oracle
Copyright © 1993, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引