|
ここでは、トランザクションを Oracle Tuxedo サーバ アプリケーションに統合する方法について説明します。始める前に、「トランザクションについて」を読む必要があります。
注意 : | Oracle Tuxedo CORBA Java クライアントと Oracle Tuxedo CORBA Java クライアント ORB は Tuxedo 8.1 で非推奨になり、今後はサポートされなくなりました。Oracle Tuxedo CORBA Java クライアントおよび Oracle Tuxedo CORBA Java クライアント ORB のテキスト参照、関連するコード サンプルはすべてサード パーティの Java ORB ライブラリの実装/実行の簡易化とプログラマによる参照だけに使用する必要があります。 |
注意 : | サード パーティの CORBA Java ORB のテクニカル サポートは、各ベンダによって提供されます。Oracle Tuxedo では、サード パーティの CORBA Java ORB に関する技術的なサポートやマニュアルは提供していません。 |
Oracle Tuxedo は、次の方法でトランザクションをサポートします。
rollback_only()
を呼び出して、トランザクションを rollback only としてマークします。これによって、現在のトランザクションがコミットされるのを防ぐことができます。エンティティ (通常はデータベース) が破損データまたは不正確なデータで更新される危険がある場合、オブジェクトは、トランザクションを rollback としてマークしなければならない場合があります。Tobj_ServantBase::deactivate_object()
オペレーションを呼び出して reason 値を渡すことを意味します。
オブジェクトは、ポーリング時に TransactionCurrent オブジェクトの rollback_only()
を呼び出すと、現在のトランザクションを拒否できます。さらに、現在のトランザクションがロールバックされる場合、オブジェクトは、データベースへの書き込みをスキップできます。現在のトランザクションを拒否するオブジェクトがない場合、トランザクションはコミットされます。
以下の節では、オブジェクトのアクティブ化ポリシーおよびトランザクション ポリシーを使用し、オブジェクト内でどのように目的のトランザクションの振る舞いを決定するかを説明します。これらのポリシーは、インタフェースに適用されます。したがって、そのインタフェースを実装しているすべてのオペレーションとオブジェクトに適用されます。
注意 : | サーバ アプリケーションが、トランザクションに参加するオブジェクトを管理している場合、そのアプリケーションの Server オブジェクトは、TP::open_xa_rm() オペレーションおよび TP::close_xa_rm() オペレーションを呼び出す必要があります。データベース接続の詳細については、「XA リソース マネージャのオープン」を参照してください。 |
Oracle Tuxedo システムは、always
トランザクション ポリシーを提供します。これは、オブジェクトが呼び出されたときにトランザクションがまだスコープ指定されていない場合、Oracle Tuxedo システムがトランザクションを自動的に開始するように、そのオブジェクトのインタフェースを定義します。そのオブジェクトの呼び出しが完了すると、Oracle Tuxedo システムは、自動的にトランザクションをコミットまたはロールバックします。サーバ アプリケーションもオブジェクト実装も、この状態で TransactionCurrent オブジェクトを呼び出す必要はありません。つまり、Oracle Tuxedo システムは、サーバ アプリケーションの代わりに自動的に TransactionCurrent オブジェクトを呼び出します。
always
トランザクション ポリシーをオブジェクトのインタフェースに割り当てるのは、以下の場合です。
オブジェクトを自動的にトランザクションに関与させる必要がある場合、実装コンフィグレーション ファイルで、そのオブジェクトのインタフェースに以下のポリシーを割り当てます。
注意 : | データベース カーソルは、複数のトランザクションにまたがることができません。ただし、C++ では、Oracle Tuxedo University サンプル アプリケーションの CourseSynopsisEnumerator オブジェクトは、データベース カーソルを使用して、University データベースからコースの概要に一致するものを検索します。データベース カーソルは、複数のトランザクションにまたがることはできないので、CourseSynopsisEnumerator オブジェクトの activate_object() オペレーションは、一致したすべてのコースの講義をメモリに読み込みます。カーソルは、イテレータ クラスによって管理されるので、CourseSynopsisEnumerator オブジェクトでは認識できません。 |
オブジェクトをトランザクションのスコープ内で呼び出すことができるようにする必要がある場合、optional
トランザクション ポリシーをそのオブジェクトのインタフェースに割り当てることができます。optional
トランザクション ポリシーは、データベース書き込みオペレーションを実行しないものの、トランザクション時に呼び出すことができるようにする必要があるオブジェクトに適しています。
以下のポリシーを、そのオブジェクトのインタフェースに対して実装コンフィグレーション ファイルで指定し、オブジェクトを必要に応じてトランザクションに関与させることができます。
トランザクション ポリシーが optional
のときに、アプリケーションの UBBCONFIG
ファイルで AUTOTRAN
パラメータが有効になっている場合、実装はトランザクションに関与します。トランザクションに関与するオブジェクトを含むサーバは、XA 準拠のリソース マネージャに関連付けられているグループ内で設定する必要があります。
オブジェクトがデータベース書き込みオペレーションを実行しており、オブジェクトがトランザクションに関与できるようにする必要がある場合は、always
トランザクション ポリシーを割り当てる方が適切です。ただし、目的に応じて optional
ポリシーを使用し、TransactionCurrent オブジェクトに対する呼び出しで書き込みオペレーションをカプセル化できます。つまり、オブジェクトがまだトランザクション内にスコープ指定されていない場合、データを書き込むオペレーション内で、トランザクションを開始およびコミットまたはロールバックするために TransactionCurrent オブジェクトを呼び出し、write 文の周囲にトランザクションをスコープします。これによって、データベース書き込みオペレーションがトランザクションに関与する形で処理されます。また、パフォーマンスも効率的に発揮できるようになります。オブジェクトがトランザクションのスコープ内で呼び出されなかった場合、すべてのデータベース読み取りオペレーションは、トランザクションに関与しないため、より効率的になります。
注意 : | トランザクション ポリシーを選択してオブジェクトに割り当てる場合、使用している XA リソース マネージャの要件を把握します。たとえば、XA リソース マネージャ (Oracle 7 トランザクション マネージャ サーバなど) では、トランザクションに参加するオブジェクトが、データベース書き込みオペレーションだけでなく、読み取りオペレーションもトランザクション内でスコープ指定する必要があります (ただし、自身のトランザクションをスコープ指定することはできます)。他のリソース マネージャ (Oracle8i など) では、読み取りオペレーションおよび書き込みオペレーションのトランザクション コンテキストを必要としません。アプリケーションが、トランザクション コンテキストなしに書き込みオペレーションを実行しようとすると、Oracle8i は、アプリケーションがローカル トランザクションを明示的にコミットする必要がある場合に、暗黙的にローカル トランザクションを開始します。 |
多くの場合、オブジェクトをトランザクションから除外することは危険です。このようなオブジェクトがトランザクション時に呼び出されると、オブジェクトは例外を返し、トランザクションがロールバックされることがあります。Oracle Tuxedo CORBA には never
トランザクション ポリシーが用意されていて、これをオブジェクトのインタフェースに割り当てれば、現在のトランザクションが一時停止中でも、特定のオブジェクトをトランザクションの処理中に呼び出されないようにできます。
このトランザクション ポリシーは、XA リソース マネージャによって管理されないディスクにデータを書き込むオブジェクトなど、ロールバックできない永続的な状態をディスクに書き込むオブジェクトに適しています。クライアント アプリケーションで、呼び出しの一部がトランザクションのスコープ指定を引き起こしているかどうかを認識できない場合、クライアント/サーバ アプリケーションでこの機能を使用することは重要です。したがって、トランザクションがスコープ指定されている場合、このポリシーを持つオブジェクトが呼び出されると、トランザクションをロールバックできるようになります。
トランザクションがスコープ指定されているときにオブジェクトの呼び出しを防ぐには、実装コンフィグレーション ファイルで、そのオブジェクトのインタフェースに以下のポリシーを割り当てます。
トランザクションの過程でオブジェクトの呼び出しを許可し、ただしそのオブジェクトをトランザクションの一部にはしないことがふさわしい場合もあります。このようなオブジェクトがトランザクションの最中に呼び出された場合、トランザクションは自動的に中断します。オブジェクトに対する呼び出しが完了すると、トランザクションは自動的に再開します。Oracle Tuxedo CORBA は、この目的のために ignore
トランザクション ポリシーを提供します。
ignore
トランザクション ポリシーは、通常はデータをディスクに書き込まないファクトリなどのオブジェクトに適している場合があります。ファクトリをトランザクションから除外することで、そのファクトリは、トランザクションの最中でもほかのクライアントの呼び出しに使用できるようになります。さらに、このポリシーを使用すると、トランザクションに関与しているオブジェクトを呼び出す際のオーバーヘッドが軽減されるので、サーバ アプリケーションの処理効率が向上します。
トランザクションがオブジェクトに伝播されないようにするには、実装コンフィグレーション・ファイルで、そのオブジェクトのインタフェースに以下のポリシーを割り当てます。
実装コンフィグレーション ファイルの作成方法とオブジェクトに対するポリシーの指定方法については、『Tuxedo CORBA プログラミング リファレンス』の「Oracle Tuxedo CORBA サーバ アプリケーションの作成手順」の「ステップ 4 : オブジェクトのメモリ内での振る舞いの定義」を参照してください。
トランザクション マネージャ サーバ (TMS) は、オブジェクトの状態データを自動的に処理します。たとえば、drive:¥TUX8¥samples¥corba¥university¥transactions
ディレクトリの University サンプル C++ アプリケーションは、リレーショナル データベース管理サービス (RDBMS) の例として Oracle TMS を使用します。
XA リソース マネージャを使用すると、サーバ アプリケーションで管理される別のオブジェクトが、データベースとの間のデータの読み書きをどのように実行するかについて、以下のような特定の要件が適用されます。
他のリソース マネージャ (Oracle8i など) では、読み取りオペレーションおよび書き込みオペレーションのトランザクション コンテキストを必要としません。アプリケーションが、トランザクション コンテキストなしに書き込みオペレーションを実行しようとすると、Oracle8i は、アプリケーションがローカル トランザクションを明示的にコミットする必要がある場合に、暗黙的にローカル トランザクションを開始します。
XA リソース マネージャの特徴は、ロールバック時のオブジェクト状態データの処理に関する設計の問題をより簡単なものにすることです。トランザクションに関与するオブジェクトは、コミットおよびロールバック権限を XA リソース マネージャに委譲します。これによって、サーバ アプリケーションの実装は、大幅に単純化されます。
オブジェクトのインタフェースに always
または optional
トランザクション ポリシーが適用されている場合、Server オブジェクトの Server::initialize()
オペレーションの TP::open_xa_rm()
オペレーションを呼び出す必要があります。リソース マネージャは、UBBCONFIG
ファイルの GROUPS
セクションにある OPENINFO
パラメータで提供された情報を基に開かれます。デフォルト バージョンの Server::initialize()
オペレーションは、自動的にリソース マネージャを開きます。
データをディスクに書き込まず、トランザクションに参加しているオブジェクト (通常、トランザクション ポリシーは optional
) がある場合、TP::open_xa_rm()
オペレーションへの呼び出しを含める必要があります。その呼び出しでは、ヌル リソース マネージャを指定します。
Server オブジェクトの Server::initialize()
オペレーションが、XA リソース マネージャを開く場合は、Server::release()
オペレーションに以下の呼び出しを含めます。
TP::close_xa_rm();
Oracle Tuxedo CORBA クライアント/サーバ アプリケーションでトランザクションが必要な場合、トランザクションをいくつかの方法でオブジェクト状態管理に統合できます。通常、Oracle Tuxedo CORBA は、アプリケーションのロジック、またはオブジェクトが永続状態をディスクに書き込む方法を変更せずに、オペレーション呼び出しの間、自動的にトランザクションをスコープ指定できます。
通常、Oracle などの XA リソース マネージャを使用すると、ロールバック時のオブジェクト状態データの処理に関する設計の問題をより簡単にできます (Oracle リソース マネージャは、Oracle Tuxedo CORBA University サンプル C++ アプリケーションで使用されます)。トランザクションに関与するオブジェクトは、コミットおよびロールバック権限を XA リソース マネージャに委譲します。これによって、サーバ アプリケーションの実装は、大幅に単純化されます。つまり、トランザクションに関与するプロセス バウンドまたはメソッド バウンド オブジェクトは、トランザクション時にデータベースに書き込みを実行し、トランザクションのロールバック時にリソース マネージャに従ってデータベースに書き込まれたデータをロールバックできます。
transaction
アクティブ化ポリシーは、トランザクションの作業が完了するまで書き込みたくない、または書き込めないメモリ内の状態をディスクに保持するオブジェクトに適しています。transaction
アクティブ化ポリシーをオブジェクトに割り当てると、オブジェクトは、以下のようになります。
トランザクションの作業が完了したら、Oracle Tuxedo CORBA は、DR_TRANS_COMMITTING
または DR_TRANS_ABORTED
のいずれかの可能性がある reason
コードを渡す、各トランザクション バウンド オブジェクトの Tobj_ServantBase::deactivate_object()
オペレーションを呼び出します。変数が DR_TRANS_COMMITTING
の場合、オブジェクトは、データベース書き込みオペレーションを呼び出すことができます。変数が DR_TRANS_ABORTED
の場合、オブジェクトは、データベース書き込みオペレーションをスキップします。
transaction
アクティブ化ポリシーのオブジェクトへの割り当ては、以下のような場合に適しています。
ロールバックの対象となる可能性のあるデータベース書き込みオペレーションの数を減らすことができるので、これによって、パフォーマンスがより効率的になります。
Oracle Tuxedo CORBA が、reason コード DR_TRANS_COMMITTING
を渡す場合、オブジェクトは必要に応じて TransactionCurrent オブジェクトの rollback_only()
を呼び出すことができます。Tobj_ServantBase::deactivate_object()
オペレーション内で rollback_only()
を呼び出した場合、deactivate_object()
は再び呼び出されません。
トランザクションがコミットされてからデータベースに書き込まれるまでオブジェクトが待機できるようにするには、実装コンフィグレーション ファイルで、そのオブジェクトのインタフェースに以下のポリシーを割り当てます。
注意 : | トランザクション バウンド オブジェクトは、Tobj_ServantBase::deactivate_object() オペレーション内でトランザクションを開始したり、ほかのオブジェクトを呼び出したりすることはできません。deactivate_object() 内でトランザクション バウンド オブジェクトが唯一可能な呼び出しは、データベースへの書き込みオペレーションです。 |
注意 : | また、トランザクションに関与するオブジェクトがある場合、そのオブジェクトを管理する Server オブジェクトは、データをディスクに書き込まない場合でも、XA リソース マネージャを開く、または閉じるための呼び出しを含める必要があります (データをディスクに書き込まない、トランザクションに関与するオブジェクトがある場合、ヌル リソース マネージャを指定します)。XA リソース マネージャのオープンおよびクローズの詳細については、「XA リソース マネージャのオープン」と「XA リソース マネージャのクローズ」を参照してください。 |
Oracle Tuxedo CORBA クライアント/サーバ アプリケーションにユーザ定義の例外を含めるには、以下の手順を実行する必要があります。
たとえば、Transactions サンプル C++ アプリケーションは、ユーザ定義の例外 TooManyCredits
のインスタンスを含んでいます。クライアント アプリケーションが学生をコースに登録しようとしたときに、学生が登録可能なコースの最大数を超えている場合、サーバ アプリケーションはこの例外を返します。クライアント アプリケーションは、この例外を受け取ると、学生をコースに登録するトランザクションをロールバックします。ここでは、サンプルとして TooManyCredits
例外を使用し、Oracle Tuxedo CORBA クライアント/サーバ アプリケーションでユーザ定義の例外をどのように定義および実装できるかを説明します。
クライアント/サーバ アプリケーションの OMG IDL ファイルでは、以下の作業を行います。
TooManyCredits
例外は、学生が登録できる単位の最大数を表す short 型の整数値を渡すために定義します。したがって、TooManyCredits
例外の定義には、以下の OMG IDL 文が含まれます。exception TooManyCredits
{
unsigned short maximum_credits;
};
Registrar
インタフェースの register_for_courses()
オペレーションに対する OMG IDL 文を示したものです。NotRegisteredList register_for_courses(
in StudentId student,
in CourseNumberList courses
) raises (
TooManyCredits
);
例外を使用するオペレーションの実装で、次の C++ 例のように例外を送出するコードを記述します。
if ( ...) {
UniversityZ::TooManyCredits e;
e.maximum_credits = 18;
throw e;
学生を登録するプロセスを実装するために、Transactions サンプル アプリケーションは、以下の作業を実行します。
register_for_courses()
オペレーションは、リスト内の各コースに対して、ループ処理で以下の作業を繰り返し実行し、登録要求を処理します。register_for_courses()
オペレーションは、クライアント アプリケーションにパラメータ NotRegisteredList
を返します。このパラメータには、登録に失敗したコースのリストが含まれています。
NotRegisteredList
の値が空の場合、クライアント アプリケーションはトランザクションをコミットします。
NotRegisteredList
値にコースが含まれていない場合、クライアント アプリケーションは、登録に成功したコースに対する登録プロセスを完了するかどうかを指定するよう学生に要求します。登録を完了するように選択した場合、クライアント アプリケーションはトランザクションをコミットします。登録を取り消すように選択した場合、クライアント アプリケーションはトランザクションをロールバックします。
TooManyCredits
例外をクライアント アプリケーションに返し、クライアント アプリケーションはトランザクション全体をロールバックします。
Transactions サンプル アプリケーションの基本設計原理は、コース登録を一度に 1 つではなくグループ単位で処理することです。この設計原理によって、Register オブジェクトに対するリモート呼び出しの数を最小化できます。
この設計を実装するにあたって、Transactions サンプル アプリケーションでは、「Oracle Tuxedo クライアントおよびサーバ アプリケーションのトランザクションの統合」で説明したトランザクションの使用モデルを 1 つ示しています。このモデルの特徴は、次のとおりです。
begin()
オペレーションを呼び出してから、Registrar オブジェクトの register_for_courses()
オペレーションを呼び出すことでトランザクションを開始します。
Register オブジェクトは、学生を可能なコースに登録し、登録プロセスが失敗したコースのリストを返します。クライアント アプリケーションは、トランザクションをコミットするかロールバックするかを選択できます。トランザクションは、クライアント アプリケーションとサーバ アプリケーションの間の会話をカプセル化します。
register_for_courses()
オペレーションは、University データベースの複数チェックを実行します。いずれか 1 つのチェックが失敗した場合、トランザクションをロールバックできます。
Transactions University サンプル アプリケーションはトランザクションに関与するため、University サーバ アプリケーションは通常、オブジェクト状態に関していくつかの点 (特にロールバック時の) を考慮する必要があります。ロールバックが発生した場合、サーバ アプリケーションは、関連するすべてのオブジェクトが、正しい状態に復元された永続状態を持つことを保証する必要があります。
Registrar オブジェクトは、データベース トランザクションで使用されるため、このオブジェクトに対する最適な設計は、そのオブジェクトがトランザクションに関与するようにすること (always
トランザクション ポリシーをこのオブジェクトのインタフェースに割り当てること) です。オブジェクト呼び出し時にトランザクションがまだスコープ指定されていない場合、Oracle Tuxedo システムは、トランザクションを自動的に開始します。
Register オブジェクトが自動的にトランザクションに関与するようにすることで、このオブジェクトによって実行されるすべてのデータベース書き込みオペレーションは、クライアント アプリケーションが開始したかどうかに関係なく、常にトランザクションのスコープ内で完了します。サーバ アプリケーションは XA リソース マネージャを使用し、またオブジェクトは、データベースに書き込みを実行するときにトランザクションにあることが保証されます。したがって、XA リソース マネージャがオブジェクトの代わりにロールバックまたはコミットの権限を持つことになるので、オブジェクトにはロールバックまたはコミット権限がありません。
ただし、RegistrarFactory オブジェクトは、トランザクション時に使用するデータを管理しないので、トランザクションから除外できます。オブジェクトをトランザクションから除外することで、トランザクションに課せられる処理のオーバーヘッドを最小化します。
Registrar オブジェクトがトランザクションに関与するようにするために、ICF ファイルは、Registrar
インタフェースに対して always
トランザクション ポリシーを指定します。したがって、Transactions サンプル アプリケーションでは、ICF ファイルで、Registrar
インタフェースに対して以下のオブジェクト ポリシーを指定します。
RegistrarFactory オブジェクトをトランザクションから除外するために、ICF ファイルでは、Registrar
インタフェースに対して ignore
トランザクション ポリシーを指定します。したがって、Transactions サンプル アプリケーションでは、ICF ファイルで、RegistrarFactory
インタフェースに対して以下のオブジェクト ポリシーを指定します。
Transactions サンプル アプリケーションは、オブジェクト状態データを自動的に処理する Oracle トランザクション マネージャ サーバ (TMS) を使用します。XA リソース マネージャを使用すると、サーバ アプリケーションで管理される別のオブジェクトが、データベースとの間のデータの読み書きをどのように実行するかについて、以下のような特定の要件が適用されます。
XA リソース マネージャの特徴は、ロールバック時のオブジェクト状態データの処理に関する設計の問題をより簡単なものにすることです。トランザクションに関与するオブジェクトは、コミットおよびロールバック権限を XA リソース マネージャに委譲します。これによって、サーバ アプリケーションの実装は、大幅に単純化されます。
University サンプル アプリケーションでは Oracle トランザクション マネージャ サーバ (TMS) を使用します。Oracle データベースを使用するには、Oracle 提供の特定のファイルをサーバ アプリケーションのビルド プロセスに含める必要があります。Transactions サンプル アプリケーションのビルド、コンフィグレーション、および実行の詳細については、Oracle Tuxedo オンライン マニュアルの「Transactions サンプル アプリケーション」を参照してください。UBBCONFIG
ファイルのコンフィグレーション可能な設定の詳細については、「UBBCONFIG ファイルをトランザクションに対応させて変更する」を参照してください。