Oracle Database 概要 11gリリース1(11.1) E05765-03 |
|
この章では、トランザクションを定義し、トランザクションを使用して作業を管理する方法について説明します。
この章の内容は、次のとおりです。
トランザクションは、1つ以上のSQL文を含む論理作業単位です。トランザクションはアトミック(基本)な単位です。つまり、トランザクション内のすべてのSQL文は、すべてコミット(データベースに適用)されるか、すべてロールバック(データベースから取消し)されるかのどちらかになります。
トランザクションは、最初の実行可能なSQL文から開始します。トランザクションは、COMMIT
文またはROLLBACK
文を使用して明示的に、またはDDL文を発行して暗黙的にコミットまたはロールバックされた時点で終了します。
トランザクションの概念を具体的に説明するため、銀行業務データベースについて考えてみます。銀行の顧客が普通預金口座から当座預金口座へ預金を振り替える場合、トランザクションは次の3つの別々の操作で構成されます。
Oracle Databaseでは、2つの状況が考慮されます。3つのSQL文がすべて実行されて、口座の差引残高の帳尻が合えば、トランザクションの結果をデータベースに適用できます。ただし、預金額の不足、口座番号が無効、またはハードウェア障害などの問題が原因で、トランザクション内の1つまたは2つの文が完了しない場合は、すべての口座の差引残高が正しく維持されるようにトランザクション全体をロールバックする必要があります。
図4-1に銀行のトランザクションの例を示します。
この項の内容は、次のとおりです。
正常に実行されるSQL文とコミットされるトランザクションとは異なります。正常に実行されるとは、単一の文が次の条件を満たしたことを意味します。
ただし、その文が含まれているトランザクションがコミットされるまでは、トランザクションをロールバックしてその文のすべての変更を取り消せます。正常に実行される(成功する)という表現は、トランザクションではなく、文に対して使用します。
コミットとは、ユーザーが明示的または暗黙的に、このトランザクションの変更内容を確定するように要求することを意味します。明示的な要求は、ユーザーがCOMMIT
文を発行すると発生します。暗黙的な要求は、アプリケーションの正常終了後またはデータ定義言語(DDL)操作の完了後に発生します。トランザクションがコミットされて初めて、トランザクションのSQL文による変更内容が確定され、他のユーザーがこれらの変更を参照できるようになります。トランザクションのコミット後に発行された問合せでは、コミットされた変更を参照できます。
トランザクションを開始する前に、SET
TRANSACTION
... NAME
文を使用して、トランザクションに名前を付けることができます。名前を付けることで、長時間実行のトランザクションの監視およびインダウト分散トランザクションの解決が容易になります。
実行中にSQL文のエラーが発生すると、その文のすべての効果はロールバックされます。ロールバックの効果は、その文がまったく実行されなかった場合と同じ状態にすることです。この操作が文レベルのロールバックです。
SQL文の実行中にエラーが検出されると、文レベルのロールバックが発生します。この種のエラーの一例として、主キーに重複値を挿入しようとした場合があります。1つのデッドロック(同じデータに関する競合)に単一SQL文が複数関係している場合も、文レベルのロールバックが発生します。解析中に構文エラーなどのエラーが検出された場合は、まだSQL文は実行されていないため、文レベルのロールバックは発生しません。
SQL文でエラーが発生した場合は、SQLでの実行予定の作業のみが影響を受けます。現行のトランザクションにおけるこれまでの作業に影響を及ぼすことはありません。文がDDL文の場合、その文の直前に実行された暗黙的コミットは取り消されません。
Oracle Databaseでは、領域割当てエラーが発生した場合、大規模なデータベース操作の実行を一時停止および再開することが可能です。このため、Oracleデータベース・サーバーからユーザーにエラーを戻すかわりに、管理者は対処措置を取ることができます。エラー条件が修正されると、一時停止中の操作が自動的に再開されます。
再開可能モードで文が実行されるのは、クライアントがALTER
SESSION
文を使用して、明示的にセッションの再開可能セマンティクスを使用可能にした場合のみです。
次のような場合、再開可能領域割当ては一時停止されます。
非再開可能領域割当ての場合、これらの条件ではエラーが発生し、文がロールバックされます。
文を一時停止すると、トランザクションが自動的に一時停止されます。このため、トランザクションのすべてのリソースが、一時停止文および再開文を介して保持されます。
エラー条件が(たとえば、ユーザーの介入、または他の問合せによりソート領域が解放された結果として)消滅すると、一時停止中の文が自動的に実行を再開します。
Oracle Databaseでのトランザクションは、最初の実行可能SQL文が検出された時点で開始されます。実行可能SQL文は、DML文やDDL文など、インスタンスへのコールを生成するSQL文です。
トランザクションが開始されると、Oracle Databaseはそのトランザクションを使用可能なUNDO表領域に割り当てて、新しいトランザクションのロールバック・エントリを記録します。
トランザクションは、次のいずれかの状況が発生すると終了します。
COMMIT
文またはROLLBACK
文が、SAVEPOINT
句なしで発行される場合。
CREATE
、DROP
、RENAME
またはALTER
などのDDL文が実行される場合。カレント・トランザクションにDML文が含まれている場合、Oracle Databaseは最初にそのトランザクションをコミットし、新しい単一文トランザクションとしてそのDDL文を実行し、コミットします。
1つのトランザクションが終了すると、次の実行可能SQL文によって次のトランザクションが自動的に開始されます。
この項の内容は、次のとおりです。
トランザクションをコミットするとは、トランザクション内のSQL文によって実行された変更を確定する操作のことです。
データを修正したトランザクションがコミットされる前に、次の処理が完了しています。
トランザクションをコミットすると、次の処理が実行されます。
関連項目
ロールバックとは、コミットされていないトランザクション内のSQL文によって実行されたデータ変更を取り消すことを意味します。Oracle Databaseは、UNDO表領域(またはロールバック・セグメント)を使用して古い値を格納します。REDOログには、変更の履歴が記録されます。
Oracle Databaseでは、コミットされていないトランザクション全体をロールバックできます。また、コミットされていないトランザクションの後半部分をセーブポイントと呼ばれるマーカーまでロールバックすることもできます。
次のすべてのタイプのロールバックで、同じ手順が使用されます。
セーブポイントを参照しないで、トランザクション全体をロールバックした場合、次の処理が実行されます。
関連項目
トランザクションのコンテキスト内で、セーブポイントと呼ばれる中間マーカーを宣言できます。セーブポイントは、ロング・トランザクションをいくつかの小さい部分に分割します。
セーブポイントを使用すると、ロング・トランザクション内の任意のポイントで作業に任意にマークを設定できます。これにより、そのトランザクション内の宣言されたセーブポイントからトランザクション内の現時点までの間に実行された作業を、後でロールバックできるようになります。たとえば、大規模で複雑な一連の更新のどこにでもセーブポイントを設定できるため、エラーが発生してもすべての文を再発行する必要はありません。
セーブポイントは、アプリケーション・プログラム内でも使用できます。プロシージャにいくつかのファンクションが含まれている場合は、それぞれのファンクションの開始前にセーブポイントを作成できます。そうすると、あるファンクションが失敗しても、そのファンクション開始前の状態にデータを復帰し、パラメータを修正してから再実行したり、リカバリ作業を実行するのが容易になります。
セーブポイントまでロールバックすると、Oracle Databaseはロールバック文が取得したデータ・ロックを解放します。以前にロックされていたリソースを待機していた他のトランザクションは、続行できます。以前にロックされていた行を更新しようとする他のトランザクションは、それらの行を更新できます。
トランザクションをセーブポイントまでロールバックした場合、次の処理が実行されます。
トランザクションはアクティブであり、継続できます。
セッションが待機中の場合は、トランザクションをセーブポイントまでロールバックした場合でも行のロックは解放されません。トランザクションがロックを取得できない場合に異常終了しないように、UPDATE
またはDELETE
文を発行する前に、FOR
UPDATE
... NOWAIT
を使用します。(これは、ロールバックしたセーブポイントの前に取得されたロックを参照します。セーブポイントの後に実行された文は完全にロールバックされているため、このセーブポイントの後に取得された行ロックが解放されます。)
トランザクションの名前には、簡単で覚えやすいテキスト文字列を使用できます。この名前は、トランザクションの目的を連想できるように命名します。分散トランザクションのコミット・コメントをトランザクションの名前に置換することには、次の利点があります。
V$TRANSACTION
などのデータ・ディクショナリ・ビュー内の特定のトランザクションを検索できます。
この項の内容は、次のとおりです。
トランザクションを開始する前に、SET TRANSACTION
... NAME
文を使用して、トランザクションに名前を付けます。
トランザクションに名前を付けるときは、IDと対応付けます。トランザクション名は一意の必要がないので、所有者が複数のトランザクションに同じトランザクション名を付けることも可能です。トランザクションを識別できるように任意の名前を付けることができます。
以前のリリースでは、コミット・コメントを使用してコメントをトランザクションに対応付けることができました。ただし、コメントをトランザクションに対応付けられるのは、トランザクションがコミットされているときのみです。
下位互換性を維持するため、コミット・コメントは引き続きサポートされます。ただし、トランザクション名を使用することをお薦めします。コミット・コメントは名前付きトランザクションでは処理されません。
分散データベースでは、Oracle Databaseはネットワーク全体でトランザクション制御を調整し、ネットワーク障害やシステム障害が発生した場合にもデータ整合性が保たれるようにする必要があります。
分散トランザクションとは、分散データベースにおいて複数の異なるノード上でデータを更新する、1つ以上の文を含むトランザクションのことです。
2フェーズ・コミット・メカニズムは、分散トランザクションに関係するすべてのデータベース・サーバーが、そのトランザクション内の文のすべてをコミットするか、またはすべてを取り消すかのどちらか一方のみになるように保証するものです。また、2フェーズ・コミット・メカニズムは、整合性制約、リモート・プロシージャ・コールおよびトリガーによって実行される暗黙的DML操作も保護します。
Oracle Databaseの2フェーズ・コミット・メカニズムは、分散トランザクションを発行するユーザーからはまったく意識されません。事実、ユーザーは、トランザクションが分散していることも認識する必要はありません。トランザクションの終了を示すCOMMIT
文は、自動的に2フェーズ・コミット・メカニズムをトリガーしてトランザクションをコミットします。データベース・アプリケーション本体に分散トランザクションを含めるのに、コーディングや複雑な構文の記述は必要ありません。
リカバラ(RECO
)・バックグラウンド・プロセスは、インダウト分散トランザクション(システム障害やネットワーク障害によってコミットが中断された分散トランザクション)の結果を自動的に解決します。障害が修復され、通信が再確立された後、各ローカルのOracleデータベースのRECO
プロセスが、関係するすべてのノード上でインダウト分散トランザクションを自動的にコミットするか、またはロールバックします。
長時間にわたる障害が発生した場合、Oracle Databaseでは、各ローカル管理者が障害によって発生したインダウト分散トランザクションを手動でコミットまたは取り消すことができます。このオプションによって、ローカル・データベース管理者は、長時間にわたる障害の結果として無期限にロックされる可能性のあるリソースを解放できます。
あるデータベースを過去のある時点までリカバリする必要がある場合、Oracle Databaseのリカバリ機能を使用すると、他のサイトのデータベース管理者は、自分のデータベースも過去のその同じ時点に戻すことができます。この操作により、グローバル・データベースは一貫した状態に保たれます。
自律型トランザクションは、他のトランザクションからコールできる、独立したトランザクションです。自律型トランザクションにより、コール側トランザクションのコンテキストから離れてなんらかのSQL操作を実行し、その操作をコミットまたは取り消してから、コール側トランザクションのコンテキストに戻って引き続き実行できます。
起動後の自律型トランザクションは、コール側のメイン・トランザクションの影響をまったく受けません。メイン・トランザクションによって加えられたがコミットされていない変更は取り扱わず、ロックやリソースをメイン・トランザクションと共有することもありません。自律型トランザクションによって加えられた変更は、自律型トランザクションのコミット時に他のトランザクションから見えるようになります。
自律型トランザクションは、相互にコールし合うことができます。自律型トランザクションをコールできるレベル数には、リソース制限以外の制限はありません。
自律型トランザクションとコール側トランザクションの間で、デッドロックが発生することがあります。Oracle Databaseは、この種のデッドロックを検出するとエラーを戻します。アプリケーション開発者は、デッドロック状況を回避する責任があります。
自律型トランザクションは、トランザクションのロギングや再試行カウンタなど、コール側トランザクションでコミットまたはロールバックするかどうかに関係なく、独立して実行する必要があるアクションを実装する場合に便利です。
PL/SQLブロックから自律型トランザクションをコールできます。プラグマAUTONOMOUS_TRANSACTION
を使用してください。プラグマは、コンパイラ・ディレクティブです。次の種類のPL/SQLブロックを、自律型として宣言できます。
自律型PL/SQLブロックに入ると、コール元のトランザクション・コンテキストは中断されます。この操作により、このブロック(または、そこからコールされる他のブロック)で実行されるSQL操作は、コール元のトランザクション・コンテキストの状態に依存も影響もしないことが保証されます。
自律型ブロックが他の自律型ブロックまたはそれ自身を起動する場合、コールされたブロックが、コール側ブロックとトランザクション・コンテキストを共有することはありません。ただし、自律型ブロックが自律型でないブロック(つまり、自律型として宣言されていないブロック)を起動する場合、コールされたブロックはコール側の自律型ブロックのトランザクション・コンテキストを継承します。
自律型PL/SQLブロック内のトランザクション制御文は、現在アクティブになっている自律型トランザクションにのみ適用されます。この種の文の例は、次のとおりです。
SET TRANSACTION COMMIT ROLLBACK SAVEPOINT ROLLBACK TO SAVEPOINT
同様に、メイン・トランザクション内のトランザクション制御文は、そのトランザクションにのみ適用され、コールされる自律型トランザクションには適用されません。たとえば、メイン・トランザクションを自律型トランザクションの開始前までロールバックしても、自律型トランザクションは取り消されません。
|
Copyright © 1993, 2008 Oracle Corporation. All Rights Reserved. |
|