ヘッダーをスキップ

Oracle Database 管理者ガイド
11gリリース1(11.1)

E05760-03
目次
目次
索引
索引

戻る 次へ

32 分散トランザクションの概念

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

分散トランザクションの概要

分散トランザクションは1つ以上の文からなり、それらが個別に、またはグループとして、分散データベースの複数ノードのデータを更新します。たとえば、図32-1に示すデータベース構成を考えます。

図 32-1    分散システム


画像の説明

scottによって実行される次の分散トランザクションは、ローカルのsalesデータベース、リモートのhqデータベース、およびリモートのmaintデータベースを更新します。

UPDATE scott.dept@hq.us.acme.com
  SET loc = 'REDWOOD SHORES'
  WHERE deptno = 10;
UPDATE scott.emp
  SET deptno = 11
  WHERE deptno = 10;
UPDATE scott.bldg@maint.us.acme.com
  SET room = 1225
  WHERE room = 1163;
COMMIT;


注意:

トランザクションのすべての文が1つのリモート・ノードのみを参照している場合、そのトランザクションは分散トランザクションではなくリモート・トランザクションです。 


分散トランザクションでは、次の2種類の操作が許可されます。

DMLおよびDDLトランザクション

分散トランザクションでサポートされているデータ操作言語(DML)およびデータ定義言語(DDL)操作は、次のとおりです。

DML文およびDDL文はパラレルに実行でき、ダイレクト・ロード・インサート文はシリアルに実行できます。ただし、次の制限に注意してください。

トランザクション制御文

サポートされているトランザクション制御文は、次のとおりです。

分散トランザクションのセッション・ツリー

分散トランザクションで文が発行されると、データベースはトランザクションに参加しているすべてのノードのセッション・ツリーを定義します。セッション・ツリーとは、セッション間の関係とセッションのロールを表す階層モデルです。セッション・ツリーの例を図32-2に示します。

図 32-2    セッション・ツリーの例


画像の説明

分散トランザクションのセッション・ツリーに参加しているすべてのノードは、次に示すロールを1つ以上持ちます。

ロール  説明 

クライアント 

異なるノードに属するデータベース内の情報を参照するノード。 

データベース・サーバー 

別のノードからの情報の要求を受け取るノード。 

グローバル・コーディネータ 

分散トランザクションの実行元ノード。 

ローカル・コーディネータ 

他のノードのデータを強制的に参照して、自身のトランザクション部分を完了するノード。 

コミット・ポイント・サイト 

グローバル・コーディネータの指示に従ってトランザクションをコミットまたはロールバックするノード。 

分散トランザクションのノードが果たすロールは、次の条件によって決まります。

クライアント

情報を別のノードのデータベースから参照するとき、ノードはクライアントとして機能します。参照先のノードはデータベース・サーバーです。図32-2のノードsalesは、warehouseデータベースおよびfinanceデータベースが稼働しているノードのクライアントです。

データベース・サーバー

データベース・サーバーは、クライアントがデータを要求する要求先データベースが稼働しているノードです。

図32-2では、salesノードのアプリケーションは、warehouseノードおよびfinanceノードのデータにアクセスする分散トランザクションを開始します。したがって、sales.acme.comはクライアント・ノードのロールを持ち、warehouseおよびfinanceはどちらもデータベース・サーバーのロールを持ちます。この例では、salesはデータベース・サーバーとクライアントを兼務しています。これは、アプリケーションがsalesデータベースのデータも変更するためです。

ローカル・コーディネータ

自身の分散トランザクション部分を完了するために他のノードのデータを参照する必要があるノードのことを、ローカル・コーディネータと呼びます。図32-2では、salesは自身が直接参照しているwarehouseノードおよびfinanceノードを調整するので、ローカル・コーディネータになります。ノードsalesはまた、トランザクションに関係するすべてのノードを調整することから、グローバル・コーディネータにもなります。

ローカル・コーディネータは、自身が直接やり取りするノードの間で次のようにトランザクションを調整する役目を果たします。

グローバル・コーディネータ

分散トランザクションの実行元であるノードのことを、グローバル・コーディネータと呼びます。分散トランザクションを発行するデータベース・アプリケーションは、グローバル・コーディネータとして機能しているノードに直接接続します。たとえば、図32-2では、ノードsalesで発行されたトランザクションは、データベース・サーバーwarehouseおよびfinanceの情報を参照します。したがって、sales.acme.comは、この分散トランザクションのグローバル・コーディネータになります。

グローバル・コーディネータは、セッション・ツリーの親またはルートになります。グローバル・コーディネータは、分散トランザクション処理中に次の操作を実行します。

コミット・ポイント・サイト

コミット・ポイント・サイトの役割は、グローバル・コーディネータの指示に従ってコミットまたはロールバックの操作を開始することです。システム管理者は、すべてのノードにコミット・ポイント強度を割り当てることで、セッション・ツリー内のノードの1つをコミット・ポイント・サイトとして必ず指定します。コミット・ポイント・サイトには、最も重要なデータを格納するノードを選択してください。

図32-3は、salesがコミット・ポイント・サイトとして機能している分散システムの例です。

図 32-3    コミット・ポイント・サイト


画像の説明

コミット・ポイント・サイトは、分散トランザクションに関係する他のすべてのノードと次の点で区別されます。

分散トランザクションのコミットの仕組み

分散トランザクションは、コミット・ポイント以外のすべてのサイトで準備が完了した後、コミットされたとみなされますが、実際には、トランザクションはコミット・ポイント・サイトで先にコミットされています。コミット・ポイント・サイトのREDOログは、このノードで分散トランザクションがコミットされるとただちに更新されます。

コミット・ポイント・ログにはコミットの記録があります。そのため、たとえ参加中のノードの一部がまだ準備完了状態であり、それらのノードで実際にトランザクションがコミットされていない場合であっても、トランザクションはコミットされたとみなされます。同様の意味で、コミット・ポイント・サイトでコミットがまだログに記録されていない場合には、分散トランザクションはコミットされていないとみなされます。

コミット・ポイント強度

データベース・サーバーには、必ずコミット・ポイント強度を割り当てる必要があります。データベース・サーバーが分散トランザクション内で参照される場合、そのコミット・ポイント強度の値によって、2フェーズ・コミットにおける役割が決まります。具体的には、このコミット・ポイント強度によって、どのノードが分散トランザクションのコミット・ポイント・サイトになり、他のすべてのノードより前にコミットするかが決まります。この値を指定するには、初期化パラメータCOMMIT_POINT_STRENGTHを使用します。ここでは、データベースがコミット・ポイント・サイトを決定する仕組みについて説明します。

準備フェーズの冒頭で決定されるコミット・ポイント・サイトは、トランザクションに参加しているノードの中からのみ選択されます。次に示す一連のイベントが発生します。

  1. データベースは、グローバル・コーディネータが直接参照しているノードの中で、最も高いコミット・ポイント強度を持つノードをコミット・ポイント・サイトとして選択します。

  2. 最初に選択されたノードは、このトランザクションの情報を取得する必要のあるノードの中で、自身よりも高いコミット・ポイント強度を持っているノードがないかを判断します。

  3. トランザクションで直接参照しているノードの中で最も高いコミット・ポイント強度を持つノードか、またはそのノードのサーバーの中でより高いコミット・ポイント強度を持つもののどちらかが、コミット・ポイント・サイトになります。

  4. 最終的なコミット・ポイント・サイトが決定した後、グローバル・コーディネータは、トランザクションに参加しているすべてのノードに準備応答を送ります。

図32-4は、各ノードのコミット・ポイント強度(かっこ内の値)を示したセッション・ツリーの例です。また、コミット・ポイント・サイトとして選択されたノードも示しています。

図 32-4    コミット・ポイント強度とコミット・ポイント・サイトの決定


画像の説明

コミット・ポイント・サイトを決定するときは、次の条件が適用されます。

図32-4のように、コミット・ポイント・サイトとグローバル・コーディネータがセッション・ツリーの異なるノードになることもあります。各ノードのコミット・ポイント強度は、最初に接続が確立されたときにコーディネータに渡されます。コーディネータは、2フェーズ・コミット時のコミット・ポイント・サイトを効率的に選択するために、自身が直接やり取りしている各ノードのコミット・ポイント強度を保持しています。そのため、コミットが発生するたびにコーディネータとノード間でコミット・ポイント強度を交換する必要がありません。

関連項目:

 

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

ローカル・データベースのトランザクションとは異なり、分散トランザクションには複数のデータベースでのデータの変更が伴います。そのため、データベースは、トランザクションの変更のコミットまたはロールバックを自己完結単位として調整する必要があり、分散トランザクションの処理はより複雑になります。言い換えれば、トランザクション全体がコミットするか、またはトランザクション全体がロールバックするかのどちらかの結果になります。

データベースは、2フェーズ・コミット・メカニズムを使用することで、分散トランザクションにおけるデータの整合性を保証します。準備フェーズでは、トランザクション内の開始ノードが他の参加ノードに対して、トランザクションをコミットまたはロールバックすることを確約するように要求します。コミット・フェーズでは、開始ノードがすべての参加ノードに対して、トランザクションをコミットするように要求します。この結果が達成できない場合、すべてのノードはロールバックするように要求されます。

分散トランザクションに参加しているすべてのノードは、必ず同じ動作を実行します。つまり、ノードすべてがトランザクションをコミットするか、またはノードすべてがトランザクションをロールバックします。データベースは、分散トランザクションのコミットまたはロールバックを自動的に制御および監視しており、2フェーズ・コミット・メカニズムを使用してグローバル・データベース(トランザクションに参加しているデータベースの集まり)の整合性を維持します。このメカニズムは完全に透過的であり、ユーザーやアプリケーション開発者の側でプログラミングを行う必要はまったくありません。

コミット・メカニズムは、次の各フェーズで構成されています。データベースは、ユーザーが分散トランザクションをコミットすると、必ずこれらのフェーズを自動的に実行します。

フェーズ  説明 

準備フェーズ 

グローバル・コーディネータと呼ばれる開始ノードは、コミット・ポイント・サイト以外の参加ノードに対して、たとえ障害が起きた場合でもトランザクションをコミットまたはロールバックすることを確約するように要求します。準備ができないノードがある場合、トランザクションはロールバックされます。 

コミット・フェーズ 

すべての参加ノードが準備完了の応答をコーディネータに伝えると、コーディネータは、コミット・ポイント・サイトにコミットを要求します。コミット・ポイント・サイトのコミット後、コーディネータは、トランザクションをコミットするように他のすべてのノードに要求します。 

情報消去フェーズ 

グローバル・コーディネータは、トランザクションに関する情報を消去します。 

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

準備フェーズ

準備フェーズは、分散トランザクションのコミットにおける1番目のフェーズです。このフェーズでは、データベースがトランザクションを実際にコミットまたはロールバックすることはありません。ここでは、分散トランザクションで参照されているすべてのノード(「コミット・ポイント・サイト」で説明されているコミット・ポイント・サイトを除く)がコミットを準備するように指示されます。ノードは、準備を完了するために次の処理を実行します。

各ノードは、コミットの準備が完了したという応答をグローバル・コーディネータに伝えることによって、その後トランザクションをコミットまたはロールバックすることを確約します。しかし、トランザクションをコミットまたはロールバックするという決定を各ノードが一方的に下すわけではありません。この確約の意味は、この時点でインスタンス障害が発生した場合、ノードはオンライン・ログのREDOレコードを使用してデータベースをリカバリし、準備フェーズに戻すことができるということです。


注意:

ノードの準備完了後に発行した問合せは、すべてのフェーズが完了するまで、関連するロック済みデータにアクセスできません。この時間は、障害が発生しないかぎり問題にはなりません(「インダウト・トランザクションの処理方法の決定」を参照)。 


準備フェーズでの応答のタイプ

準備を指示されたノードは、次の方法で応答できます。

応答  意味 

準備完了 

ノードのデータの変更が分散トランザクション内の文によって完了しており、ノードの準備が正常に完了しています。  

読取り専用 

ノードで変更されるデータがない(問合せのみ)か、または変更できないので、準備は不要です。  

異常終了 

ノードが正常に準備できません。  

準備レスポンス

ノードの準備が正常に完了すると、ノードは準備完了メッセージを発行します。このメッセージは、ノードの変更レコードがオンライン・ログに格納されており、ノードでコミットまたはロールバックのどちらかを実行できる準備が整っていることを示します。また、このメッセージによって、トランザクションに対して保持されているロックが障害発生時にも残ることが保証されます。

読取り専用応答

ノードが準備を要求されたときに、データベースにアクセスするSQL文がノードのデータを変更しない場合、ノードは読取り専用メッセージで応答します。このメッセージは、ノードがコミット・フェーズに参加しないことを示します。

分散トランザクションの全部または一部が読取り専用になるケースとして、次の3つがあります。

ケース  条件  結果 

一部読取り専用 

次のいずれかが発生した場合

  • 1つ以上のノードで問合せのみが発行された。

  • データが変更されない。

  • トリガーの起動または制約違反のために変更がロールバックされた。

 

読取り専用ノードは、準備を要求されたときに自身のステータスを認識します。読取り専用ノードは、読取り専用応答をローカル・コーディネータに伝えます。この結果、データベースは読取り専用ノードを以降の処理から除外するので、コミット・フェーズがより高速に完了します。  

準備フェーズでの完全な読取り専用 

次のすべてが発生した場合

  • データが変更されない。

  • トランザクションがSET TRANSACTION READ ONLY文で始まっていない。

 

準備フェーズ時にすべてのノードが読取り専用であることを認識するので、コミット・フェーズは不要になります。グローバル・コーディネータにはすべてのノードが読取り専用かどうかわからないため、グローバル・コーディネータは引き続き準備フェーズを実行する必要があります。 

2フェーズ・コミットなしの完全な読取り専用 

次のすべてが発生した場合

  • データが変更されない。

  • トランザクションがSET TRANSACTION READ ONLY文で始まっている。

 

このトランザクションでは問合せのみが許可されるため、グローバル・コーディネータは、2フェーズ・コミットを実行する必要がありません。また、システム変更番号(SCN)の調整がノード間でグローバルに行われるため、他のトランザクションによる変更によってグローバル・トランザクション・レベルの読込み一貫性が損なわれることはありません。このトランザクションでは、UNDOセグメントは使用されません。 

分散トランザクションが読取り専用に設定されている場合、そのトランザクションでUNDOセグメントは使用されません。多数のユーザーがデータベースに接続していて、ユーザーのトランザクションがREAD ONLYに設定されていない場合は、それらのトランザクションが問合せを実行するのみであっても、UNDO領域が割り当てられます。

異常終了時のエラー

ノードは、正常に準備できないときに次の処理を実行します。

  1. トランザクションが現在保持しているリソースを解放し、トランザクションのローカル部分をロールバックします。

  2. 分散トランザクション内で自身を参照しているノードに対し、異常終了メッセージで応答します。

これらの処理は、分散トランザクションに関係している他のノードに伝播します。これにより、他のノードはトランザクションをロールバックできるので、グローバル・データベースのデータの整合性が保証されます。この応答によって、「トランザクションに関係しているすべてのノードが同じ論理時間ですべてコミットするかまたはすべてロールバックする」という分散トランザクションの基本原則が守られます。

準備フェーズの手順

準備フェーズを完了するために、コミット・ポイント・サイトを除く各ノードは次の手順を実行します。

  1. ノードは、自身の(以降参照する各ノード)に対して、コミットの準備をするように要求します。

  2. ノードは、トランザクションによって自分自身のデータまたは子のデータが変更されるかどうかをチェックします。データが変更されない場合、ノードは残りの手順を省略し、読取り専用応答を返します(「読取り専用応答」を参照)。

  3. データが変更される場合、ノードはトランザクションのコミットに必要なリソースを割り当てます。

  4. ノードは、トランザクションによる変更に対応するREDOレコードをREDOログに保存します。

  5. ノードは、トランザクションに対して保持されているロックが障害発生時にも残ることを保証します。

  6. ノードは、準備レスポンスを開始ノードに伝えます(「準備レスポンス」を参照)。あるいは、自身またはその子のいずれかが準備の試行に失敗した場合は、異常終了応答を伝えます(「異常終了時のエラー」を参照)。

これらの処理によって、ノードが後で自身のトランザクションをコミットまたはロールバックできることが保証されます。この後、準備完了ノードは、グローバル・コーディネータからCOMMITまたはROLLBACK要求を受け取るまで待機します。

各ノードの準備が完了した後、分散トランザクションはインダウトと呼ばれる状態になります(「インダウト・トランザクション」を参照)。分散トランザクションは、すべての変更がコミットまたはロールバックされるまで、インダウト状態のままです。

コミット・フェーズ

コミット・フェーズは、分散トランザクションのコミットにおける2番目のフェーズです。このフェーズになる前に、分散トランザクションで参照されるコミット・ポイント・サイト以外のすべてのノードが準備を完了していること、つまり、コミット・ポイント・サイト以外のすべてのノードがトランザクションのコミットに必要なリソースを確保していることが保証されます。

コミット・フェーズの手順

コミット・フェーズは次の手順で構成されています。

  1. グローバル・コーディネータは、コミット・ポイント・サイトにコミットを指示します。

  2. コミット・ポイント・サイトは、コミットを実行します。

  3. コミット・ポイント・サイトは、コミットが完了したことをグローバル・コーディネータに伝えます。

  4. グローバル・コーディネータおよびローカル・コーディネータは、すべてのノードに対してトランザクションをコミットするように指示するメッセージを送ります。

  5. 各ノードで、データベースは分散トランザクションのローカル部分をコミットし、ロックを解放します。

  6. 各ノードで、データベースは、トランザクションのコミットが完了したことを示す追加のREDOエントリをローカルREDOログに記録します。

  7. 各参加ノードは、自身のコミットが完了したことをグローバル・コーディネータに伝えます。

コミット・フェーズが完了するときは、分散システムの全ノードのデータについて一貫性が保たれています。

グローバル・データベースの一貫性の保証

コミットされた各トランザクションには、そのトランザクション内部のSQL文によって行われた変更を一意に識別するためのSCNが対応付けられます。SCNは、データベースのコミット済バージョンを一意に識別する内部的なタイムスタンプの役割を持ちます。

分散システムでは、次の処理がすべて発生したときに、通信中のノードのSCNが調整されます。

特に、分散システムのノード間でSCNが調整されることにより、文とトランザクションの両方のレベルでグローバルな読込み一貫性が保証されるという利点があります。必要であれば、グローバルな時間ベースのリカバリを実行することもできます。

準備フェーズ時に、データベースは、トランザクションに関係しているすべてのノードで最も高いSCNを判断します。次に、コミット・ポイント・サイトにおいて最も高いSCNでトランザクションをコミットします。さらに、すべての準備完了ノードに対して、コミットの指示とともにコミットSCNを送ります。

関連項目:

読込み一貫性におけるタイム・ラグ問題の管理の詳細は、「読込み一貫性の管理」を参照してください。 

情報消去フェーズ

参加ノードが自身のコミットの完了をコミット・ポイント・サイトに通知した後、コミット・ポイント・サイトは、トランザクションに関する情報を消去できます。次の手順が発生します。

  1. すべてのノードのコミットが完了したことをグローバル・コーディネータから通知された後、コミット・ポイント・サイトは、このトランザクションに関するステータス情報を消去します。

  2. コミット・ポイント・サイトは、ステータス情報を消去したことをグローバル・コーディネータに伝えます。

  3. グローバル・コーディネータは、トランザクションに関する自分自身の情報を消去します。

インダウト・トランザクション

2フェーズ・コミット・メカニズムは、すべてのノードがコミットされるかまたはロールバックを一斉に実行することを保証します。システムやネットワークのエラーのために、3つのフェーズのいずれかが失敗した場合はどうなるのでしょうか。この場合、トランザクションはインダウトになります。

分散トランザクションは、次の要因によってインダウトになる可能性があります。

マシン、ネットワークまたはソフトウェアの問題が解決されると、RECOプロセスによってインダウト・トランザクションが自動的に解決されます。RECOがトランザクションを解決できるまで、データは読取りおよび書込みの両方についてロックされます。読取りをブロックするのは、データベースが問合せに対してどのバージョンのデータを表示すればよいかを判断できないためです。

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

インダウト・トランザクションの自動解決

データベースでは、多くの場合、インダウト・トランザクションは自動的に解決されます。たとえば、次の使用例においてlocalremoteの2つのノードがあるとします。ローカル・ノードはコミット・ポイント・サイトです。ユーザーscottは、localに接続してlocalremoteを更新する分散トランザクションを実行し、コミットします。

準備フェーズ中の障害

図32-5は、分散トランザクションの準備フェーズ中に障害が発生したときの一連のイベントを示しています。

図 32-5    準備フェーズ中の障害


画像の説明

次の手順が発生します。

  1. ユーザーSCOTTLocalに接続して分散トランザクションを実行します。

  2. グローバル・コーディネータ(この例ではコミット・ポイント・サイトを兼務)は、コミット・ポイント・サイト以外のすべてのデータベースに対して、コミットまたはロールバックの指示があったときにその動作を実行することを確約するように要求します。

  3. remoteデータベースが、localに準備応答を発行する前にクラッシュします。

  4. トランザクションは、リモート・サイトのリストア時に、RECOプロセスによって各データベースで最終的にロールバックされます。

コミット・フェーズ中の障害

図32-6は、分散トランザクションのコミット・フェーズ中に障害が発生したときの一連のイベントを示しています。

図 32-6    コミット・フェーズ中の障害


画像の説明

次の手順が発生します。

  1. ユーザーScottlocalに接続して分散トランザクションを実行します。

  2. グローバル・コーディネータ(この場合はコミット・ポイント・サイトを兼務)は、コミット・ポイント・サイト以外のすべてのデータベースに対して、コミットまたはロールバックの指示があったときにその動作を実行することを確約するように要求します。

  3. コミット・ポイント・サイトは、コミットの確約を示す準備完了メッセージをremoteから受け取ります。

  4. コミット・ポイント・サイトはトランザクションをローカルにコミットし、それからコミット・メッセージをremoteに送ってコミットを要求します。

  5. remoteデータベースはコミット・メッセージを受け取りましたが、ネットワーク障害のために応答できません。

  6. トランザクションは、ネットワークがリストアされた後、RECOプロセスによってリモート・データベースで最終的にコミットされます。

    関連項目:

    障害状況の説明と、2フェーズ・コミット中に障害が発生した場合のデータベースによる解決方法の詳細は、「インダウト・トランザクションの処理方法の決定」を参照してください。 

インダウト・トランザクションの手動解決

次の場合のみ、インダウト・トランザクションを手動で解決する必要があります。

インダウト・トランザクションの解決が複雑になる場合があります。その場合は、次の手順を実行する必要があります。

インダウト・トランザクションのSCNの関連性

SCNは、コミット済みバージョンのデータベースの内部的なタイムスタンプです。Oracle Databaseサーバーは、SCNクロック値を使用することでトランザクションの一貫性を保証します。たとえば、ユーザーがトランザクションをコミットするとき、データベースはそのコミットのSCNをREDOログに記録します。

データベースは、SCNを使用して、異なるデータベース間での分散トランザクションを調整します。たとえば、データベースは、次のときにSCNを使用します。

  1. アプリケーションがデータベース・リンクを使用して接続を確立するとき

  2. 分散トランザクションが、それに関係しているすべてのデータベースの中で最も高いグローバルSCNでコミットされるとき

  3. コミット・グローバルSCNが、トランザクションに関係しているすべてのデータベースに送られるとき

SCNは、トランザクションが失敗した場合も含め、トランザクションの同期化されたコミット・タイムスタンプとして機能するため、分散トランザクションにとって非常に重要な存在です。トランザクションがインダウトになった場合、管理者はこのSCNを使用して、グローバル・データベースへの変更を調整できます。トランザクション・コミットのグローバルSCNは、分散リカバリの実行時など、後でトランザクションの識別に使用することもできます。

分散トランザクション処理: 事例

この使用例では、ある会社がsales.acme.comおよびwarehouse.acme.comという異なるOracle Databaseサーバーを持っています。ユーザーが売上レコードをsalesデータベースに挿入すると、対応付けられたレコードがwarehouseデータベースで更新されます。

この分散処理の事例では、次のことを示します。

第1段階: クライアント・アプリケーションによるDML文の発行

営業部門で、営業担当がSQL*Plusを使用して売上注文を入力し、コミットします。アプリケーションは次のようなSQL文を発行し、salesデータベースに注文を入力して、warehouseデータベースのinventory表を更新します。

CONNECT scott@sales.acme.com ...;
INSERT INTO orders ...;
UPDATE inventory@warehouse.acme.com ...;
INSERT INTO orders ...;
UPDATE inventory@warehouse.acme.com ...;
COMMIT;

これらのSQL文は単一の分散トランザクションの一部であり、発行されるすべてのSQL文がユニットとして成功または失敗することが保証されています。文をユニットとして扱うことにより、注文が設定されているにもかかわらず、注文を反映するように在庫が更新されていないという事態を防ぐことができます。実際は、トランザクションによってグローバル・データベースのデータの一貫性が保証されています。

トランザクションの各SQL文が実行されると、図32-7のようにセッション・ツリーが定義されます。

図 32-7    セッション・ツリーの定義


画像の説明

トランザクションの次の点に注意してください。

この段階では、この分散トランザクションのセッション・ツリーの定義が完了します。ツリー内の各ノードは、必要なデータ・ロックを獲得して、ローカル・データを参照するSQL文を実行します。これらのロックは、SQL文の実行が完了した後も、2フェーズ・コミットが完了するまで保持されます。

第2段階: Oracle Databaseによるコミット・ポイント・サイトの判別

データベースは、COMMIT文の直後にコミット・ポイント・サイトを判別します。図32-8のように、グローバル・コーディネータのsales.acme.comがコミット・ポイント・サイトとして判別されます。

関連項目:

コミット・ポイント・サイトの判別の詳細は、「コミット・ポイント強度」を参照してください。 

図 32-8    コミット・ポイント・サイトの判別


画像の説明

第3段階: グローバル・コーディネータによる準備応答の送信

準備段階では、次の手順が実行されます。

  1. データベースがコミット・ポイント・サイトを判別した後、グローバル・コーディネータは、コミット・ポイント・サイトを除くセッション・ツリーの直接参照先のノードすべてに準備メッセージを送ります。この例では、準備を要求されるノードはwarehouse.acme.comのみです。

  2. ノードwarehouse.acme.comは準備を試みます。トランザクション内のローカルに独立した部分をコミットし、自身のローカルREDOログにコミット情報を記録できることをノードが保証できれば、そのノードは正常に準備できます。この例では、sales.acme.comがコミット・ポイント・サイトなので、warehouse.acme.comのみが準備メッセージを受け取ります。

  3. ノードwarehouse.acme.comは、準備完了メッセージでsales.acme.comに応答します。

各ノードが準備を終えると、準備を要求した側のノードに応答メッセージが送り返されます。応答に応じて、次のいずれかの動作が発生します。

第4段階: コミット・ポイント・サイトによるコミット

コミット・ポイント・サイトによるトランザクションのコミットでは、次の手順が実行されます。

  1. ノードsales.acme.comは、warehouse.acme.comの準備が完了しているという確認を受け取り、トランザクションをコミットするようにコミット・ポイント・サイトに指示します。

  2. この時点で、コミット・ポイント・サイトはトランザクションをローカルにコミットし、この操作を自身のローカルREDOログに記録します。

warehouse.acme.comがまだコミットを完了していない場合でも、このトランザクションの結果は事前に決まっています。つまり、対象となるノードのコミットが遅れた場合でも、トランザクションはすべてのノードでコミットされます。

第5段階: コミット・ポイント・サイトによるグローバル・コーディネータへのコミットの通知

この段階では、次の手順が実行されます。

  1. コミット・ポイント・サイトは、トランザクションが完了したことをグローバル・コーディネータに伝えます。この例では、コミット・ポイント・サイトとグローバル・コーディネータが同じノードなので、必要な操作はありません。コミット・ポイント・サイトでは、トランザクションがコミットされたことがわかっています。これは、トランザクションがコミットされたことが自身のオンライン・ログに記録されているためです。

  2. グローバル・コーディネータは、分散トランザクションに関係している他のすべてのノードでトランザクションがコミットされたことを確認します。

第6段階: グローバルおよびローカル・コーディネータによる全ノードへのコミットの要求

トランザクション内のすべてのノードによるトランザクションのコミットでは、次の手順が実行されます。

  1. コミット・ポイント・サイトでのコミットがグローバル・コーディネータに通知された後、グローバル・コーディネータは、直接参照している他のすべてのノードに対してコミットを指示します。

  2. コミットの指示を受けたローカル・コーディネータは、次に自身のサーバーに対してコミットを指示し、以下同様にコミットの指示が伝播されます。

  3. グローバル・コーディネータを含む各ノードは、トランザクションをコミットし、該当するREDOログ・エントリをローカルに記録します。各ノードのコミットが完了すると、そのトランザクションのためにローカルに保持されていたリソース・ロックが解放されます。

図32-10では、コミット・ポイント・サイトとグローバル・コーディネータを兼務しているsales.acme.comが、トランザクションのローカルのコミットをすでに完了しています。この時点でsaleswarehouse.acme.comに対してトランザクションのコミットを指示します。

図 32-10    ノードへのコミットの指示


画像の説明

第7段階: グローバル・コーディネータとコミット・ポイント・サイトによるコミットの完了

トランザクションのコミットの完了は、次の手順で実行されます。

  1. すべての参照先ノードとグローバル・コーディネータがトランザクションのコミットを完了した後、グローバル・コーディネータはこれをコミット・ポイント・サイトに通知します。

  2. このメッセージを待っていたコミット・ポイント・サイトは、この分散トランザクションに関するステータス情報を消去します。

  3. コミット・ポイント・サイトは、消去が完了したことをグローバル・コーディネータに伝えます。つまり、コミット・ポイント・サイトは、分散トランザクションのコミットに関する情報をまったく保持しません。2フェーズ・コミットに関係しているすべてのノードでトランザクションのコミットが正常に完了すると、それらのノードで今後ノード自身のステータスを判断する必要はありません。したがって、このような処理が許可されます。

  4. グローバル・コーディネータは、トランザクション自体に関する情報を消去することでトランザクションを完了します。

COMMITフェーズの完了後、分散トランザクションそのものが完了します。これまで説明した手順は、1秒以内に自動的に実行されます。


戻る 次へ
Oracle
Copyright © 2001, 2008, Oracle Corporation.
All Rights Reserved.
目次
目次
索引
索引