|
Oracle Tuxedo CORBA TP フレームワークでは、ユーザが高パフォーマンスの TP アプリケーション用のサーバを作成することを可能にするプログラミング TP フレームワークを提供します。ここでは、TP フレームワークのプログラミング モデルおよびアプリケーション プログラミング インタフェース (API) について詳しく説明します。この API の使用方法については、『Tuxedo CORBA サーバ アプリケーションの開発方法』でも説明しています。
Oracle Tuxedo CORBA サーバを開発する場合、TP フレームワークは必須です。この要件は今後のリリースで緩和される予定ですが、多くの場合、TP フレームワークはアプリケーションの主要な構成部分として使用されると考えられます。
Oracle Tuxedo では、ロード バランシング、トランザクション機能、および管理機能を備えたインフラストラクチャを提供します。TP フレームワークで使用される基本 API は、Oracle が拡張した CORBA API です。TP フレームワークの API は、顧客にエクスポーズされます。Oracle Tuxedo ATMI は、TP フレームワークの API と混在して利用可能なオプションの API です。この API を使用すると、CORBA サーバと ATMI サーバが混在する環境で分散アプリケーションをデプロイできます。
Oracle Tuxedo CORBA 以前、ORB 製品は大規模環境では Oracle Tuxedo のパフォーマンスに及びませんでした。Oracle Tuxedo システムは、1 秒あたり数百のトランザクションを処理するアプリケーションをサポートしています。こうしたアプリケーションは、各要求で使用するシステム リソースを最小限に抑え、したがってスループットおよびコスト パフォーマンスを最大限に引き出す、Oracle Tuxedo のステートレス サービス プログラミング モデルを使用してビルドされます。
現在では、Oracle Tuxedo CORBA と TP フレームワークによって、Oracle Tuxedo ATMI アプリケーションと同等のパフォーマンスを持つ CORBA アプリケーションを開発できます。Oracle Tuxedo CORBA サーバは、CORBA プログラミング モデルを使用しながら、Oracle Tuxedo ステートレス サービス プログラミング モデルに近いスループット、応答時間、およびプライス パフォーマンスを実現します。
TP フレームワークでは、単純で便利な CORBA オブジェクトのさまざまな実装のサブセットを選択できます。使用できるのは、サーバサイド オブジェクトの実装を開発する場合のみです。クライアントサイド CORBA ORB を使用する場合、クライアントは、TP フレームワークが管理するサーバサイド実装を持つ CORBA オブジェクトと対話します。クライアントでは TP フレームワークの存在が意識されません。非 Oracle Tuxedo サーバ環境で実行される CORBA オブジェクトにアクセスするように作成されたクライアントは、クライアント インタフェースの変更や制約もなく、Oracle Tuxedo サーバ環境で実行される同じ CORBA オブジェクトにアクセスできます。
TP フレームワークでは、CORBA ポータブル オブジェクト アダプタ (POA) よりも使いやすく、理解も簡単で、特にエンタープライズ アプリケーション向けに準備されたサーバ環境および API が提供されます。これは、単純なサーバ プログラミング モデルと、ORBIX や VisiBroker などの ORB を使用していたプログラマにはなじみのある従来の CORBA モデルの実装です。
TP フレームワークを使用すると、次の方法でサーバ環境の複雑さを抑えて、Oracle Tuxedo CORBA サーバのプログラミングが容易になります。
TP フレームワークは、ORB および POA と連携して、次の方法でアプリケーション プログラムのフローを制御します。
TP フレームワーク API には、アプリケーション コードに CORBA オブジェクトの柔軟な状態管理スキーマを実装するためのコールバック メソッドが用意されています。状態管理では、オブジェクトを非アクティブ化したりアクティブ化したりするときのオブジェクトの状態を保存および復元する必要があります。状態管理は、サーバのパフォーマンスおよびリソース使用量に影響を与える、アクティブ化されたオブジェクトの有効期間にも関係します。アクティブ化されたオブジェクトのデフォルトの有効期間は、IDL のコンパイル時に実装に割り当てたポリシーによって制御されます。
TP フレームワークのトランザクション統合には次の機能があります。
TP フレームワークでは、サーバの停止時に、サーバが関与しているすべてのトランザクションがロールバックされ、アクティブ化されているすべての CORBA オブジェクトが非アクティブ化されます。
TP フレームワーク API の TP インタフェースには、オブジェクトの登録とユーティリティ関数を実行するメソッドが用意されています。以下のサービスが提供されます。
こうした高レベル サービスのメソッドは、開発者が CORBA POA、CORBA ネーミング サービス、および Oracle Tuxedo API を理解しなくても、基となる実装として使用できるようにすることを目的としています。基となる API 呼び出しを高レベルのメソッドのセットと一緒にカプセル化することで、プログラマは、より複雑な基本機能を理解したり使用したりすることなく、ビジネス ロジックの実現に集中することが可能となります。
状態管理では、オブジェクトを非アクティブ化したりアクティブ化したりするときのオブジェクトの状態を保存および復元する必要があります。状態管理は、サーバのパフォーマンスおよびリソース使用量に影響を与える、アクティブ化されたオブジェクトの有効期間にも関係します。TP フレームワークの外部 API には、activate_object および deactivate_object メソッドが用意されています。これらのメソッドは、状態管理コードを配置可能な場所を示します。
TP フレームワークでは、状態管理はアクティブ化ポリシーによって提供されます。このポリシーは、サーバントの作成および破棄ではなく、特定の IDL インタフェースに対するサーバントのアクティブ化および非アクティブ化を制御します。このポリシーが適用されるのは、TP フレームワークを使用する CORBA オブジェクトのみです。
アクティブ化ポリシーは、CORBA オブジェクトがメモリ内でアクティブ化しているデフォルトの期間を決定します。CORBA オブジェクトが POA 内でアクティブ化されているのは、POA のアクティブ オブジェクト マップにオブジェクト ID と既存のサーバントを関連付けるエントリが入っている場合です。オブジェクトを非アクティブ化すると、オブジェクト ID とアクティブ化されたサーバントとの関連付けが削除されます。選択できるアクティブ化ポリシーは、method (デフォルト)、transaction、process のいずれかです。
| 注意 : | アクティブ化ポリシーは、OMG IDL のコンパイル時にコンフィグレーションする ICF ファイルで設定されます。ICF ファイルの詳細については、「実装コンフィグレーション ファイル (ICF)」を参照してください。 |
method (デフォルトのアクティブ化ポリシー)
CORBA オブジェクトのアクティブ化、つまりオブジェクト ID とサーバントとの関連付けは、メソッドが終了するまで維持されます。メソッドが終了すると、オブジェクトは非アクティブ化されます。オブジェクト参照で次のメソッドが呼び出されると、CORBA オブジェクトはアクティブ化されます。つまり、オブジェクト ID が新しいサーバントに関連付けられます。この動作は、Oracle Tuxedo のステートレス サービスとほぼ同じです。
transaction
CORBA オブジェクトのアクティブ化、つまりオブジェクト ID とサーバントとの関連付けは、トランザクションが終了するまで維持されます。トランザクション中は、オブジェクトの複数のメソッドを呼び出すことができます。オブジェクトは最初のメソッド呼び出しの前にアクティブ化され、次のいずれかの方法で非アクティブ化されます。
tmshutdown または tmadmin コマンドが使用されます。これらのコマンドについては、オンライン マニュアルの『Tuxedo コマンド リファレンス』を参照してください。
transaction アクティブ化ポリシーでは、2 フェーズ コミット アルゴリズムを実行する前に、オブジェクトがトランザクションの結果に関して支持するかどうかを判断できます。オブジェクトがトランザクションのロールバックを支持する場合は、Tobj_ServantBase::deactivate_object メソッドの Current.rollback_only() を呼び出します。トランザクションのコミットを支持する場合は、Current.rollback_only() を呼び出しません。
| 注意 : | これは、Oracle Tuxedo の会話型サービスに似たリソース割り当てモデルです。ただし、このモデルの方が、システム リソースの使用量が少ないという点で、Oracle Tuxedo の会話型サービスよりもコストが小さくなります。この理由は、Oracle Tuxedo ORB のマルチコンテキスト ディスパッチ モデル、つまり、1 つのサーバ用のサーバントがメモリ内に同時に多数存在するモデルを使用しているからです。このモデルでは、多数のクライアントにサービスし、同時にアクティブ化されている多数のサーバントが 1 つのサーバ プロセスを共有できます。Oracle Tuxedo システムでは、プロセスは、会話の有効期間だけ 1 つのクライアント専用となり、1 つのサービスにのみ割り当てられます。 |
process
CORBA オブジェクトは、非アクティブ化状態で呼び出されたときにアクティブ化され、デフォルトではプロセスが終了するまでその状態を持続します。
| 注意 : | TP フレームワーク API には、activation policy が process に設定されたオブジェクトを非アクティブ化するタイミングをアプリケーションで制御するためのインタフェース メソッド (TP::deactivateEnable) が用意されています。このメソッドの説明については、「TP::deactivateEnable()」を参照してください。 |
通常、アクティブ化と非アクティブ化は、既に説明したように、TP フレームワークによって決定されます。ここで説明するテクニックでは、代替メカニズムの使い方を示します。アプリケーションでは、特定のポリシーが設定されたオブジェクトを明示的にアクティブ化および非アクティブ化するタイミングを制御できます。
アプリケーション コードでは、process アクティブ化ポリシーを使用するオブジェクトに関して、TP フレームワークのオン デマンド アクティブ化機能を無効にすることができます。アプリケーションでは、TP::create_active_object_reference 呼び出しを使用して、オブジェクトを「事前アクティブ化」、つまり呼び出しの前にアクティブ化することができます。
事前アクティブ化のしくみは次のとおりです。アプリケーションは、オブジェクト参照を作成する前に、サーバントをインスタンス化して、その状態を初期化します。アプリケーションは TP::create_active_object_reference を使用して、オブジェクトをアクティブ オブジェクト マップに追加、つまりサーバントと ObjectId を関連付けます。最初の呼び出しが行われると、TP フレームワークが、オブジェクト参照を作成したプロセスに直ちに要求を転送してから、既存のサーバントに転送します。この際、オブジェクトに対する 2 番目以降の呼び出しと同じように、Server::create_servant に次いでサーバントの activate_object メソッドを呼び出す必要はありません。こうしたオブジェクトのオブジェクト参照は別のサーバを指さないので、アクティブ化されている限り、オブジェクトがオン デマンドでアクティブ化されることはありません。
事前アクティブ化されたオブジェクトには process アクティブ化ポリシーが設定されているので、プロセスの終了または TP::deactivateEnable 呼び出しのいずれかのイベントが発生するまで、オブジェクトはアクティブ化されたままとなります。
事前アクティブ化は、アプリケーションが共有メモリなどを使用して状態を初期化して、初期状態のサーバントを同じプロセスで確立する必要がある場合に特に有用です。状態にポインタ、オブジェクト参照、または複雑なデータ構造が含まれている場合、後で別のプロセスで状態が初期化されるまで待機する処理は非常に難しくなるからです。TP::create_active_object_reference を使用すると、事前アクティブ化されたオブジェクトは、事前アクティブ化を実行したコードと必ず同じプロセスにあります。事前アクティブ化によってリソースがあらかじめ割り当てられるので、便利な手法であっても、事前アクティブ化を多用することは控える必要があります。ただし、必要に応じて適切に使用すれば、事前アクティブ化はその他の方法よりもはるかに効率的です。
適切な使い方の例として、「イテレータ」パターンを使用するオブジェクトがあります。たとえば、「database_query」メソッドから電話帳の内容のような長い項目リストがアンバウンディッド IDL シーケンスで返される可能性があるとします。メッセージ サイズも必要なメモリ量も非常に大きくなるので、こうした項目をすべてシーケンスで返すことは非効率的です。
イテレータ パターンを使用するオブジェクトは、リストを取得する最初の呼び出しで、一定数の項目をシーケンスで返し、さらに要素を取得する場合に呼び出せる「イテレータ」オブジェクトへのリファレンスも返します。イテレータ オブジェクトは初期オブジェクトによって初期化されます。つまり、初期オブジェクトはサーバントを作成してその状態を設定し、反復処理が長い項目リストのどの位置で止まっているか (データベース、問い合わせパラメータ、カーソルなどを指すポインタ) を追跡します。
初期オブジェクトは、TP::create_active_object_reference を使用して、イテレータ オブジェクトを事前初期化します。また、初期オブジェクトは、そのオブジェクトへのオブジェクト参照を作成してクライアントに返します。クライアントは、イテレータ オブジェクトを繰り返し呼び出して、たとえば、呼び出しごとにリスト内の 100 項目を取得します。こうした場合の事前初期化の利点は、複雑な状態を使用できるということです。通常は、初期オブジェクトに制御がある間に、すべての情報をコンテキスト (呼び出しフレーム) に持っているメソッドを使用して、そうした状態を最初に設定する方法が最も簡単です。
クライアントがイテレータ オブジェクトの操作を終了したら、初期オブジェクトで最終メソッドを呼び出して、イテレータ オブジェクトを非アクティブ化します。初期オブジェクトは、TP::deactivateEnable メソッドを呼び出すイテレータ オブジェクトのメソッドを呼び出すことで、イテレータ オブジェクトを非アクティブ化します。つまり、イテレータ オブジェクトは、TP::deactivateEnable メソッドを自身に対して呼び出します。
通常、この方法で事前アクティブ化されたオブジェクトの場合、クラッシュすると状態を回復することはできません。最初の遅延アクティブ化で設定するには、状態が複雑すぎるか、一貫性を維持できないと考えられるからです。これは、基本的にオブジェクトが 1 回のアクティブ化期間のみ有効であることを示しており、効果的なオブジェクトのテクニックです。
ただし、「1 回」という使い方のために問題が発生する場合があります。クライアントが状態を含むプロセスにつながるオブジェクト参照を保持しており、クラッシュするとその状態を再度作成することができないので、クライアントの次の呼び出しが自動的にオブジェクトを新しくアクティブ化することがないように注意を払う必要があります。新しくアクティブ化するとオブジェクトが不当な状態を持つことになるからです。
この問題を解決する方法は、オブジェクトが TP フレームワークによって自動的にアクティブ化されないようにすることです。activate_object 呼び出しの結果として TobjS::ActivateObjectFailed 例外を TP フレームワークに提供した場合、TP フレームワークはアクティブ化を実行せず、CORBA::OBJECT_NOT_EXIST 例外をクライアントに返します。クライアントにはイテレータ (または類似) パターンについての知識があるので、こうした状況について想定しています。クライアントは反復を再度開始するように準備する必要があります。
| 注意 : | TP フレームワーク自体でオブジェクト参照が有効ではなくなったことを検出できるようになれば、こうした保護措置は不要になります。特に、activate_object メソッドが呼び出される可能性を考慮せずに済みます。TP フレームワークが変更される場合、activate_object は呼び出されず、フレームワーク自体が OBJECT_NOT_EXIST 例外を生成するようになります。 |
process アクティブ化ポリシーを設定したオブジェクトを事前アクティブ化できるように、process アクティブ化ポリシーを設定したオブジェクトを非アクティブ化するよう要求することもできます。事前アクティブ化する機能と非アクティブ化を要求する機能は独立しています。つまり、オブジェクトがどのようにアクティブ化されたかに関係なく、オブジェクトを明示的に非アクティブ化することができます。
アプリケーションのメソッドは、TP::deactivateEnable 使用して、オブジェクトを非アクティブ化するように要求できます。TP::deactivateEnable を呼び出して、オブジェクトが非アクティブ化された場合、CORBA オブジェクトに対する以降の呼び出しによって、以前にアクティブ化されたように、同じプロセスで再度アクティブ化されるとは限りません。ObjectId とサーバントとの関連付けは、CORBA オブジェクトがアクティブ化されてから、サーバ プロセスが停止されるか、アプリケーションが TP::deactivateEnable を呼び出すまで持続します。関連付けが解除された後、オブジェクトをもう一度呼び出すと、Oracle Tuxedo コンフィグレーション パラメータで許可された場所で再度アクティブ化することができます。
TP::deactivateEnable には 2 つの形式があります。最初の形式 (パラメータなし) では、実行中のオブジェクトは、呼び出しが行われたメソッドの終了後に非アクティブ化されます。非アクティブ化するかどうかはオブジェクト自身が決定します。通常、この非アクティブ化は、「サインオフ」シグナルとして機能するメソッド呼び出しで行われます。
2 番目の形式の TP::deactivateEnable では、サーバは、オブジェクトが実行中かどうかにかかわりなく、アクティブ化されている任意のオブジェクトを非アクティブ化するよう要求できます。つまり、どのサーバもオブジェクトを非アクティブ化するよう要求できます。この形式では、非アクティブ化するオブジェクトを識別するパラメータを指定します。transaction アクティブ化ポリシーが設定されたオブジェクトを明示的に非アクティブ化することはできません。トランザクションが終了するまで、そうしたオブジェクトを安全に非アクティブ化することができないからです。
TP::deactivateEnable 呼び出しで、TP フレームワークはサーバントの deactivate_object メソッドを呼び出します。TP フレームワークが deactivate_object を呼び出す正確なタイミングは、非アクティブ化されるオブジェクトの状態によって異なります。オブジェクトが実行中でない場合、TP フレームワークは、制御が呼び出し側に戻る前に、オブジェクトを非アクティブ化します。オブジェクトが実行中の場合もあります。これは常にパラメータを持たない TP::deactivateEnable の場合です。この形式では、実行中のオブジェクトが参照されるからです。この場合、TP::deactivateEnable には、オブジェクトが直ちに非アクティブ化されたかどうか通知されません。
| 注意 : | TP::deactivateEnable(interface, object id, servant) メソッドを使用すると、オブジェクトを非アクティブ化できます。ただし、オブジェクトがトランザクションに参加している場合、オブジェクトが非アクティブ化されるのは、トランザクションがコミットまたはロールバックしたときです。トランザクションがコミットまたはロールバックする前にオブジェクトに対して呼び出しが行われた場合、オブジェクトは非アクティブ化されません。 |
| 注意 : | 必要な動作が確実に実行されるようにするには、オブジェクトがトランザクションに参加していないことを確認するか、TP::deactivateEnable() を呼び出してからトランザクションが終了するまでオブジェクトに対して呼び出しが行われないようにします。 |
サーバントとは、IDL インタフェースのオペレーションを実装するメソッドを格納した C++ クラスのことです。ユーザはサーバントのコードを記述します。TP フレームワークは、サーバント コードのメソッドを呼び出して要求を満たします。サーバントは、C++ の「new」文で作成され、C++ の「delete」文で破棄されます。ここでは、作成と破棄、および作成と破棄のタイミングについて説明します。
通常、TP フレームワークはサーバントの有効期間を完全に制御します。基本モデルでは、アクティブ化されていないオブジェクトに対する要求を受け取ると、TP フレームワークがサーバントを取得してから、activate_object メソッドを呼び出してサーバントをアクティブ化します。非アクティブ化する場合、TP フレームワークはサーバントの deactivate_object メソッドを呼び出してから、サーバントを破棄します。
「TP フレームワークがサーバントを取得」するフェーズは、TP フレームワークが、サーバントを作成する必要がある場合に、ユーザ作成のサーバ メソッド、Server::create_servant または ServerBase::create_servant_with_id を呼び出す、ということです。このとき、アプリケーション コードは要求されたサーバントを指すポインタを返す必要があります。ほとんどの場合、アプリケーションは、サーバントの新しいインスタンスを作成する C++ の「new」文を使用することで、この処理を行います。「サーバントを破棄」するフェーズは、TP フレームワークが、実際に削除するサーバントへのリファレンスを削除する、ということです。
アプリケーションでは、サーバントを作成および削除する動作が将来のバージョンの製品で変更される可能性があることを考慮しておく必要があります。アプリケーションは現在の動作に依存してはなりませんが、サーバントを再利用するサーバント コードを記述する必要があります。具体的には、サーバント コードは、サーバントが C++ の「new」文によって作成されていない場合でも、動作しなければなりません。TP フレームワークは、サーバントが非アクティブ化されてからも削除しないで、後で再度アクティブ化することができます。つまり、サーバントは、コンストラクタでサーバントが作成されたときではなく、サーバントの activate_object メソッドでコールバックされたときに自身を初期化しなければならないということです。
アプリケーションで TP フレームワークの標準的なサーバントの使い方を変更するには、2 つのテクニックがあります。サーバントの取得に関するものとサーバントの破棄に関するものです。
アプリケーションでは、明示的な事前アクティブ化により、「取得」メカニズムを変更できます。この場合、アプリケーションはサーバントを作成して初期化してから、サーバントをアクティブ化された状態として宣言するように TP フレームワークに要求します。こうしたサーバントは、TP::create_active_object_reference 呼び出しによって TP フレームワークに渡されると、その他のサーバントとまったく同じように TP フレームワークによって扱われます。唯一の違いは、作成および初期化の方法です。
アプリケーションは、サーバントの破棄を TP フレームワークに任せる代わりに自身で処理することで、「破棄」メカニズムを変更できます。サーバントが Server::create_servant、ServerBase::create_servant_with_id または TP::create_active_object_reference によって TP フレームワークに通知されると、TP フレームワークのデフォルト動作は、そのサーバント自体を削除することになります。この場合、アプリケーション コードでは、非アクティブ化後にそのサーバントへのリファレンスを使用してはなりません。
ただし、アプリケーションから TP フレームワークに対して、TP フレームワークがサーバントを非アクティブ化した後にサーバントを破棄しないように指示することはできます。サーバントの処理は、サーバントのクラス全体について行うのではなく、サーバントを識別するパラメータを付けて Tobj_ServantBase::_add_ref を呼び出すことで、個別に行います。
| 注意 : | Oracle Tuxedo リリース 8.0 以降で作成するアプリケーションでは、TP::application_responsibility() メソッドの代わりに Tobj_ServantBase::_add_ref メソッドを使用します。TP::application_responsibility() メソッドと違い、add_ref() メソッドは引数を取りません。 |
サーバントの処理を行うアプリケーションの利点は、サーバントを新しく作成せずに済むことです。サーバントの取得に大きなコストが伴う場合、アプリケーションではサーバントを保存しておいて、後でそれを再利用すると便利です。特に便利なのは事前アクティブ化されたオブジェクトのサーバントの場合ですが、一般的にも言えることです。たとえば、TP フレームワークが次に Server::create_servant または ServerBase::create_servant_with_id を呼び出した場合、アプリケーションは以前に保存しておいたサーバントを返すことができます。
また、アプリケーションがサーバントの処理を行うようにすると、アプリケーションは、サーバントが必要でなくなったとき、つまりほかの C++ インスタンスと同じように、リファレンス数がゼロになったときに、Tobj_ServantBase::_remove_ref を使用してサーバントを削除しなければなりません。_remove_ref() メソッドのしくみについては、「Tobj_ServantBase::_remove_ref()」を参照してください。
シングル スレッドおよびマルチスレッドのサーバ アプリケーションの作成方法については、『Tuxedo CORBA サーバ アプリケーションの開発方法』を参照してください。
CORBA オブジェクトがアクティブ化されている間、オブジェクトの状態はサーバント内に格納されます。TP::create_active_object_reference を使用するアプリケーションと違い、状態は、オブジェクトが最初に呼び出されたとき、つまりオブジェクト参照の作成後に CORBA オブジェクトに対してメソッドが最初に呼び出されたときと、オブジェクトが非アクティブ化されて以降の呼び出しで初期化しなければなりません。CORBA オブジェクトが非アクティブ化されている間、オブジェクトの状態をサーバントがアクティブ化されていたプロセスの外部に保存する必要があります。オブジェクトの状態は、共有メモリ、ファイル、データベースなどに保存できます。CORBA オブジェクトを非アクティブ化する前に、オブジェクトの状態を保存して、オブジェクトがアクティブ化されたときに状態を復元する必要があります。
プログラマは、オブジェクトの状態の構成要素と、オブジェクトを非アクティブ化する前に何を保存し、オブジェクトをアクティブ化した後に何を復元するかを決定する必要があります。
CORBA オブジェクトの状態をサーバント クラスのコンストラクタまたはデストラクタで初期化、保存、または復元してはなりません。TP フレームワークが、サーバントのインスタンスを非アクティブ化するときに削除しないで、再利用する可能性があるからです。サーバントのインスタンスの作成および削除のタイミングについては、一切保証されません。
以降のセクションでは、トランザクション ポリシーとトランザクションの使い方について説明します。
CORBA オブジェクトがグローバル トランザクションに参加できるかどうかは、コンパイル時に実装に割り当てられたトランザクション ポリシーによって制御されます。以下のポリシーを割り当てることができます。
| 注意 : | トランザクション ポリシーは、OMG IDL のコンパイル時にコンフィグレーションする ICF ファイルで設定されます。ICF ファイルの詳細については、「実装コンフィグレーション ファイル (ICF)」を参照してください。 |
never
実装はトランザクションに関与しません。このインタフェース用に作成されるオブジェクトは、トランザクションに関与できません。このポリシーを設定した実装がトランザクションに関与した場合、例外 (INVALID_TRANSACTION) が生成されます。インタフェースの UBBCONFIG ファイルで指定した AUTOTRAN ポリシーは無視されます。
ignore
実装はトランザクションに関与しません。このポリシーでは、この実装からトランザクション内の要求を送信できます。インタフェースの UBBCONFIG ファイルで指定した AUTOTRAN ポリシーは無視されます。
optional (デフォルトの transaction_policy)
実装はトランザクションに関与できます。要求がトランザクションに関係する場合、オブジェクトはトランザクションに関与できます。トランザクションに関与するオブジェクトを含むサーバは、XA 準拠のリソース マネージャに関連付けられているグループ内で設定する必要があります。AUTOTRAN パラメータがインタフェースの UBBCONFIG ファイルで指定されている場合、AUTOTRAN は有効になります。
always
実装はトランザクションに関与します。オブジェクトは、必ずトランザクションに関与する必要があります。トランザクション外の要求が送信されると、システムはトランザクションを自動的に開始してからメソッドを呼び出します。トランザクションは、メソッド終了時にコミットされます (これは、optional トランザクション ポリシーを設定したオブジェクトに対して AUTOTRAN を指定した場合とほぼ同じ動作ですが、この動作を有効にするには管理コンフィグレーションが必要な点が異なります。また、管理コンフィグレーションによってオーバーライドすることはできません)。トランザクションに関与するオブジェクトを含むサーバは、XA 準拠のリソース マネージャに関連付けられているグループ内でコンフィグレーションする必要があります。
| 注意 : | optional ポリシーは、管理コンフィグレーションによって影響を受ける唯一のトランザクション ポリシーです。システム管理者が UBBCONFIG ファイルまたは管理ツールを使用して、AUTOTRAN 属性をインタフェースに対して設定すると、既にトランザクションに関与している場合を除いて、オブジェクトの呼び出し時にトランザクションが自動的に開始されます。つまり、always ポリシーを指定した場合と同じ動作になります。 |
トランザクションの初期化には、次の 2 つの方法があります。
CosTransactions::Current::begin() オペレーションを使用した、アプリケーション コードによる方法。この処理は、クライアントでもサーバでも行うことができます。このオペレーションの説明については、『Tuxedo CORBA トランザクション』を参照してください。always に設定されている。optional に設定されており、インタフェースに対して AUTOTRAN が設定されている。
詳細については、『Tuxedo CORBA トランザクション』を参照してください。
一般に、トランザクションの結果を処理することは、開始プロセスの責任です。したがって、次のことが言えます。
Oracle Tuxedo システムによって、以下の動作が強制的に実行されます。
CORBA::OBJ_ADAPTER 例外がクライアント アプリケーションで発生します。この例外はトランザクションがサーバ アプリケーションで初期化されたために発生します。したがって、クライアント アプリケーションでは、TRANSACTION_ROLLEDBACK のようなトランザクション エラーを予想していません。
CORBA オブジェクトは、メソッド呼び出し内のトランザクションの一時停止および再開に関する規則に厳密に従う必要があります。以下に、これらの規則と規則に違反した場合のエラーについて説明します。
CORBA オブジェクト メソッドが実行を開始すると、トランザクションに関する状態は次の 3 つのいずれかになります。
| 注意 : | オペレーション呼び出しを受信したときにトランザクションを自動的に開始する場合、各 CORBA インタフェースに対して、AUTOTRAN を Yes に設定します。AUTOTRAN を Yes に設定しても、インタフェースが既にトランザクション モードにある場合は無効です。AUTOTRAN の詳細については、『Tuxedo CORBA トランザクション』を参照してください。 |
| 注意 : | お勧めしません。メソッドがトランザクションを再開する前に、トランザクションがタイムアウトしたり、アボートされたりする可能性があります。 |
CORBA::OBJ_ADAPTER 例外をクライアントに生成し、トランザクションがロールバックされます。CORBA::OBJ_ADAPTER 例外は、クライアント アプリケーションがトランザクションを初期化していないために発生します。したがって、クライアント アプリケーションでは、トランザクション エラーが発生することを予想していません。 CORBA::OBJ_ADAPTER 例外をクライアント アプリケーションに生成し、トランザクションは Oracle Tuxedo システムによってロールバックされます。CORBA::OBJ_ADAPTER 例外は、クライアント アプリケーションがトランザクションを初期化していないために発生します。したがって、クライアント アプリケーションでは、トランザクション エラーが発生することを予想していません。
Oracle Tuxedo CORBA トランザクションには、以下の制約が適用されます。
CORBA::INVALID_TRANSACTION 例外が返されます。CORBA::OBJ_ADAPTER 例外が発生します。Server::initialize() でトランザクションを開始した場合、メソッドから復帰する前にトランザクションをコミットまたはロールバックしなければなりません。アプリケーションがトランザクションを開始していない場合、TP フレームワークはサーバを停止します。この理由は、Server::initialize メソッドの終了後に制御をアプリケーションに戻す予測可能な方法がないからです。transaction アクティブ化ポリシーが設定されている場合、かつメソッドに渡された理由コードが DR_TRANS_COMMITTING または DR_TRANS_ABORTED の場合、Tobj_ServantBase::deactivate_object メソッドからはどの CORBA オブジェクトに対しても呼び出しは行われません。こうした呼び出しに対しては、CORBA::BAD_INV_ORDER 例外が生成されます。
SQL およびグローバル トランザクションを使用する場合には、次のガイドラインに従ってください。
| 注意 : | この点は、アプリケーションが XA ライブラリを使用して Oracle サーバに接続している場合には問題になりません。こうしたアプリケーションはグローバル トランザクションでしか処理を行えないからです。Oracle サーバでは、XA を使用している場合にローカル トランザクションが許可されません。 |
Current.begin() を明示的に使用して開始されたグローバル トランザクションやシステムによって暗黙的に開始されたグローバル トランザクションを終了することはできません。各データベース製品でグローバル トランザクションを使用する場合のその他の制約については、データベース ベンダのマニュアルで確認してください。
CORBA オブジェクトは、トランザクション処理の 2 つの段階で、トランザクションの結果に関与することができます。
Current.rollback_only メソッドを使用すると、現在のトランザクションをロールバックすることが唯一の結果になることが保証されます。Current.rollback_only() は、どの CORBA オブジェクト メソッドからも呼び出せます。
トランザクション バウンドのアクティブ化ポリシーが設定された CORBA オブジェクトでは、トランザクションの処理終了後にトランザクションをコミットするかロールバックするかを判断できます。これらのオブジェクトには、TP フレームワークが 2 フェーズ コミット アルゴリズムを開始する前で、deactivate_object メソッドを呼び出すときに、トランザクションの処理が終了したことが通知されます。
ただしこの動作は、process または method アクティブ化ポリシーが設定されたオブジェクトには適用されません。CORBA オブジェクトがトランザクションをロールバックする場合、CORBA オブジェクトは Current::rollback_only を呼び出します。トランザクションをコミットすることを支持する場合、CORBA オブジェクトはそのメソッドを呼び出しません。ただし、コミットすることを支持してもトランザクションが実際にコミットされるとは限りません。その後、ほかのオブジェクトがトランザクションをロールバックすることを支持する可能性があるからです。
| 注意 : | SQL カーソルのユーザは、method または process アクティブ化ポリシーが設定されたオブジェクトを使用する場合に注意する必要があります。プロセスは、クライアントが開始したトランザクション内で SQL カーソルを開きます。典型的な SQL データベース製品の場合、クライアントがトランザクションをコミットすると、そのトランザクション内で開かれていたすべてのカーソルは自動的に閉じられますが、オブジェクトにはカーソルが閉じられたことが通知されません。 |
トランザクションのタイムアウトが発生すると、トランザクションをロールバックすることが唯一の結果になるようにトランザクションにマークされ、CORBA::TRANSACTION_ROLLEDBACK 標準例外がクライアントに返されます。新しい要求を送信しようとすると、トランザクションがアボートされるまで、必ず CORBA::TRANSACTION_ROLLEDBACK 例外となって失敗します。
サーバ インスタンスに障害が発生したとき、その時点でサーバ インスタンスが何を処理していたかを常に判別できるとは限りません。たとえば、クライアント要求を処理した後、応答を返す前にサーバ インスタンスに障害が発生した場合、要求が処理されたかどうかを判別することはできません。通常、応答が返ってこなければ、ユーザは要求を再試行します。これが、余分な要求が発生する原因になります。
Oracle Tuxedo CORBA には、可用性の拡張を目的として、IIOP クライアント フェイルオーバのサポートが追加されました。IIOP クライアント フェイルオーバは、CORBA リモート クライアントが自動的に代替 ISL に接続し、障害時に要求を再試行するための透過的なメカニズムを提供します。
IIOP クライアント フェイルオーバでは、インタフェース実装をべき等元としてマークします。べき等元実装は、悪影響なしで反復できる実装です。たとえば、SET BALANCE です。
インタフェース実装をべき等元としてマークするためには、実装コンフィグレーション ファイル (ICF) で retry_policy オプションを使用して再試行ポリシーを設定する必要があります。ICF の詳細については、「実装コンフィグレーション ファイル (ICF)」を参照してください。
retry_policy オプションには 2 種類の設定があります。
再試行ポリシーは、MIB(5) T_IFQUEUE および T_INTERFACE クラスに追加された TA_RTPOLICY 属性でチェックすることもできます。TA_RTPOLICY 属性の値は、never または always です。
IIOP クライアント フェイルオーバのサポートを開始するには、UBBCONFIG ファイルの *SERVERS セクションにある -C warn|none オプションを使用して ISL サーバを指定する必要があります。
このオプションを使用すると、クライアント orb から ISL への非公式な直接接続が許可されます。-C warn|none を使用して指定されていない ISL サーバは、候補 IIOP のゲートウェイ プールには配置されません。その結果、クライアントはこれらの ISL サーバにはフェイルオーバしません。
以下に示す UBBCONFIG ファイルの例では、1 行目と 2 行目に指定された ISL サーバでクライアント フェイルオーバがサポートされます。3 行目の ISL サーバでは、クライアント フェイルオーバはサポートされません。
*SERVERS ISL SRVGRP=SYS_GRP1 SRVID=10 CLOPT="-A -- -C warn -n //myhost1:2468" ISL SRVGRP=SYS_GRP2 SRVID=20 CLOPT="-A -- -C none -n //myhost2:2469" ISL SRVGRP=SYS_GRP3 SRVID=30 CLOPT="-A -- -n //myhost3:2470"
IIOP クライアント フェイルオーバは、以下の場合にはサポートされません。
」
Tuxedo CORBA C++ クライアントでは、WebLogic クラスタ サーバへのフェイルオーバとロード バランシングがサポートされています。詳細については、WebLogic 10.0 マニュアルの「クラスタのフェイルオーバとレプリケーション」および「クラスタでのロード バランシング」を参照してください。
リリース 8.0 の Oracle Tuxedo CORBA には、パフォーマンスの拡張を目的として並行オブジェクトのサポートが追加されています。並行オブジェクト機能を利用すると、特定アプリケーションのすべてのビジネス オブジェクトをステートレス オブジェクトとして指定できます。1 つのドメインの 1 つのサーバでしか実行できない、ステートフル ビジネス オブジェクトと異なり、ステートレス ビジネス オブジェクトは 1 つのドメインのすべてのサーバで実行できます。並行オブジェクトの利点は以下のとおりです。
並行オブジェクトの詳細については、『Oracle Tuxedo CORBA アプリケーションのスケーリング、分散、およびチューニング』を参照してください。
並行オブジェクトを実装するために、同時実行ポリシー オプションが ICF ファイルに追加されています。特定のアプリケーションに対して並行オブジェクトを選択するには、同時実行ポリシー オプションをユーザ制御に設定します。ユーザ制御の同時実行を選択すると、ビジネス オブジェクトはアクティブ オブジェクト マップ (AOM) に登録されないので状態を持たなくなり、同時に複数のサーバ上でアクティブ化されることができます。このため、こうしたオブジェクトは「並行オブジェクト」と呼ばれます。
ユーザ制御の同時実行を選択した場合、サーバントの実装は以下のいずれかの記述に該当しなければなりません。
リリース 8.0 の Oracle Tuxedo ソフトウェアでは、実装コンフィグレーション ファイル (ICF) が変更されてユーザ制御の同時実行をサポートするようになりました。コード リスト 3-2 では、このサポートのための変更箇所が太字で強調されています。ICF の構文の説明については、「ICF の構文」を参照してください。
[#pragma activation_policy method|transaction|process]
[#pragma transaction_policy never|ignore|optional|always][#pragma concurrency_policy user_controlled|system_controlled][Module module-name {]
implementation [implementation-name]
{
implements (module-name::interface-name);
[activation_policy (method|transaction|process);]
[transaction_policy (never|ignore|optional|always);]
[concurrency_policy (user_controlled|system_controlled);]};
[};]
ユーザ制御の同時実行は、ファクトリ ベース ルーティング、すべてのアクティブ化ポリシー、およびすべてのトランザクション ポリシーで使用できます。これらの機能との対話は次のとおりです。
オブジェクトの作成時にユーザがファクトリ ベース ルーティングを指定すると、オブジェクトはそのグループ内のサーバにルーティングされます。オブジェクト キーにはファクトリ ベース ルーティングで選択されたグループが含まれていますが、クライアント ルーティング コードでは、インタフェースにユーザ制御の同時実行が設定されていることを認識し、必要なグループを指定します。これは、Oracle Tuxedo の通常のルーティングを使用して行われます。
TP フレームワークでは、ユーザ制御の同時実行を設定されたアクティブ化されたオブジェクトは、システム制御の同時実行を設定されたオブジェクトと同じように扱われます。TP フレームワークでは、オブジェクトに関する情報はローカルの AOM に格納され、必要に応じて activate_object および deactivate_object メソッドが呼び出されます。ただし、オブジェクトは AOM 内にエントリを持たないので、TP フレームワークは AOM のルーチンを呼び出しません。たとえば、アクティブ化されたオブジェクトは AOM ハンドルを持たないので、停止時に AOM からエントリを削除する呼び出しは行われません。
TP フレームワークでは、ユーザ制御の同時実行を設定されたアクティブ化されたオブジェクトは、システム制御の同時実行を設定されたオブジェクトと同じように扱われます。TP フレームワークがトランザクションのイベントに対してコールバックされると、トランザクションに関与するユーザ制御のオブジェクトに関する情報が AOM に格納されます。ステートフル オブジェクトと比べて並行オブジェクトをトランザクションで使用する場合の主な違いは、AOM が GTRID 情報を格納するために使用されず、AOM のルーチンがトランザクション情報を更新または取得するために呼び出されないことです。
| 注意 : | ユーザ制御の同時実行性に関して次の制約があります。TP::create_active_object_reference は、ユーザ制御の同時実行性が設定されたインタフェースを渡されると、TobjS::IllegalOperation 例外を送出します。AOM はユーザ制御の同時実行性が設定されている場合に使用されないので、TP フレームワークにはアクティブ化されたオブジェクトをこのサーバに接続する方法がありません。 |
ここでは、TP フレームワーク API について説明します。この API の使用方法については、『Tuxedo CORBA サーバ アプリケーションの開発方法』でも説明しています。
TP フレームワークは以下のコンポーネントで構成されています。
Server C++ クラス。アプリケーション固有のサーバ初期化および終了ロジック用の仮想メソッドを持っています。ServerBase C++ クラス。マルチスレッド サーバ アプリケーション用の仮想メソッドを持っています。Tobj_ServantBase C++ クラス。オブジェクトの状態管理用の仮想メソッドを持っています。TP C++ クラス。以下の処理を実行するためのメソッドを用意しています。ULOG) ファイルへのメッセージの記録
TP フレームワークの可視部分は、2 種類のオペレーションで構成されています。
Server インタフェースには、アプリケーション固有のサーバ初期化および終了ロジック用のコールバック メソッドが用意されています。このインタフェースには、オブジェクトをアクティブ化するためにサーバントが必要な場合に、サーバントを作成するためのコールバック メソッドも用意されています。
Server インタフェースのメソッドの説明については、「ServerBase インタフェース」を参照してください。
C++ マッピングについては、「ServerBase インタフェース」を参照してください。
serverBase インタフェースを使用すると、マルチスレッド処理機能の利点を最大限に活用できます。ServerBase クラスを継承する独自の Server クラスを作成することもできます。このクラスでは以下のものが提供されます。
ServerBase クラスでは、以前のリリースの Server クラスで利用可能だったオペレーションを使用できます。Server クラスは、ServerBase クラスを継承します。
これらのオペレーションは、シングル スレッド アプリケーションでもマルチスレッド アプリケーションでも使用できます。
これらのメソッドは、マルチスレッド サーバ アプリケーションでのみ使用できます。
| 注意 : | プログラマは、Server クラスのメソッドを定義する必要があります。ServerBase クラスのメソッドには、デフォルトの実装があります。 |
class OBBEXPDLLUSER ServerBase {
public: virtual CORBA::Boolean
initialize(int argc, char** argv) = 0; virtual void
release() = 0; virtual Tobj_Servant
create_servant(const char* interfaceName) = 0; // デフォルト実装の指定
virtual Tobj_Servant
create_servant_with_id(const char* interfaceName,
const char* stroid); virtual CORBA::Boolean
thread_initialize(int argc, char** argv); virtual void
thread_release();};class Server : public ServerBase {
public: CORBA::Boolean initialize(int argc, char** argv);
void release();
Tobj_Servant create_servant(const char* interfaceName);
};
サーバントを作成して C++ オブジェクトをインスタンス化します。
class Server {
public:
Tobj_Servant create_servant(const char* interfaceName);
};interfaceName
TP::create_object_reference() を使用してオブジェクト参照を作成した場合に指定したインタフェース名、または TP::create_active_object_reference() の呼び出しで使用したオブジェクト参照のインタフェース名と同じになります。この名前を使用して、作成する必要があるサーバントを決定できます。
Server::create_servant() で例外が送出された場合、TP フレームワークが例外を捕捉します。アクティブ化は失敗します。CORBA::OBJECT_NOT_EXIST() 例外がクライアントに返されます。また、エラー メッセージが、次のように例外型ごとにユーザ ログ (ULOG) ファイルに書き込まれます。
TobjS::CreateServantFailed
"TPFW_CAT:23: ERROR: オブジェクトの活性化時 - アプリケーションが TobjS::CreateServantFailed を上げました。Reason = reason。インタフェース = interfaceName、OID = oid。"
TobjS::OutOfMemory
"TPFW_CAT:22: ERROR: オブジェクトの起動時 - アプリケーションが例外 TobjS::OutOfMemory を上げました。Reason = reason。インタフェース = interfaceName、OID = oid。"
CORBA::Exception
"TPFW_CAT:28: ERROR: オブジェクトの活性化時 - CORBA の例外をアプリケーションが処理しませんでした。例外 ID = exceptionID。インタフェース = interfaceName、OID = oid。"
exceptionID は例外のインタフェース ID を示し、interfaceName と oid はそれぞれ呼び出された CORBA オブジェクトのインタフェース ID とオブジェクト ID を示します。
その他の例外
"TPFW_CAT:29: ERROR: オブジェクトの活性化時 - 不明な例外をアプリケーションが処理しませんでした。例外 ID = exceptionID。インタフェース = interfaceName、OID = oid。"
exceptionID は例外のインタフェース ID を示し、interfaceName と oid はそれぞれ呼び出された CORBA オブジェクトのインタフェース ID とオブジェクト ID を示します。
create_servant メソッドは、要求がサーバに送信され、その要求を満たすための利用可能なサーバントがない場合に、TP フレームワークによって呼び出されます。TP フレームワークは、作成するサーバントのインタフェース名を指定して create_servant メソッドを呼び出します。サーバ アプリケーションでは、適切な C++ オブジェクトをインスタンス化して、そのオブジェクトを指すポインタを返します。通常、このメソッドは、インタフェース名の switch 文を格納しており、インタフェース名に従って新しいオブジェクトを作成します。
| 注意 : | サーバ アプリケーションでは、CORBA オブジェクトがアクティブ化されるたびにこのメソッドが呼び出されることを前提にしてはなりません。また、サーバ アプリケーションでは、CORBA オブジェクトのサーバント クラスのコンストラクタまたはデストラクタで、CORBA オブジェクトの状態を処理してはなりません。TP フレームワークがアクティブ化時にサーバントを再利用する場合や、非アクティブ化時にサーバントを破棄しない場合が考えられるからです。 |
Tobj_Servant
create_servant() を呼び出した場合、または何らかの理由でサーバントを作成できなかった場合は、NULL 値が返されます。
create_servant メソッドが NULL ポインタを返した場合、アクティブ化は失敗します。CORBA::OBJECT_NOT_EXIST() 例外がクライアントに返されます。また、次のメッセージがユーザ ログ (ULOG) に書き込まれます。
"TPFW_CAT:23: ERROR: オブジェクトの活性化時 - アプリケーションが TobjS::CreateServantFailed を上げました。Reason = Application's Server::create_servant returned NULL。インタフェース = interfaceName、OID = oid。"
interfaceName は呼び出されたインタフェースのインタフェース ID を示し、oid は対応するオブジェクト ID を示します。
| 注意 : | このリリースでは、ObjectId の長さに関する制約がなくなりました。 |
対象オブジェクト用のサーバントを作成します。このメソッドは、シングル スレッドおよびマルチスレッド サーバ アプリケーションの開発をサポートします。
Tobj_Servantcreate_servant_with_id (const char*interfaceName,
const char*stroid);
interfaceName
stroid
TP フレームワークは、要求がサーバに送信されたときに、その要求を満たすための利用可能なサーバントがない場合に create_servant_with_id メソッドを呼び出します。TP フレームワークは、作成するサーバントのインタフェースとサーバントに関連付けられるオブジェクトのオブジェクト ID を渡します。サーバ アプリケーションでは、適切な C++ オブジェクトをインスタンス化して、そのオブジェクトを指すポインタを返します。通常、このメソッドは、インタフェース名の switch 文を格納しており、インタフェース名に従って新しいオブジェクトを作成します。オブジェクト ID を指定すると、サーバントの実装では、サーバント インスタンスの作成時に対象オブジェクトの情報を基にさまざまな決定を行えます。リエントラントのサポートは、サーバントの実装で対象オブジェクトの情報を利用する方法の一例です。
ServerBase クラスには、インタフェース名を渡す標準の create_servant メソッドを呼び出す create_servant_with_id のデフォルト実装が用意されています。このデフォルト実装では、対象のオブジェクト ID パラメータは無視されます。
| 注意 : | サーバ アプリケーションでは、CORBA オブジェクトがアクティブ化されるたびにこのメソッドが呼び出されることを前提にしてはなりません。また、サーバ アプリケーションでは、CORBA オブジェクトのサーバント クラスのコンストラクタまたはデストラクタで、CORBA オブジェクトの状態を処理してはなりません。TP フレームワークがアクティブ化時にサーバントを再利用する場合や、非アクティブ化時にサーバントを破棄しない場合が考えられるからです。 |
Tobj_Servant
Tobj_Servant simple_per_request_server::create_servant_with_id(
const char* intf_repos_id, const char* stroid)
{
TP::userlog("create_servant_with_id called in thread %ld",
(unsigned long)SIMPTHR_GETCURRENTTHREADID);
// このオブジェクト ID に基づいて必要な初期化を
// 実行する
return create_servant(intf_repos_id);
}
アプリケーションが、データベースへのログイン、既知のオブジェクト ファクトリの作成および登録、グローバル変数の初期化などのアプリケーション固有の初期化手続きを実行できるようにします。
class Server {
public: CORBA::Boolean initialize(int argc, char** argv);};
argc および argv 引数がコマンドラインから渡されます。argc 引数には、サーバ名が格納されます。argv 引数には、アプリケーション固有の最初のコマンドライン オプションが格納されます (存在する場合)。
コマンドライン オプションは、SERVERS セクションにあるサーバのエントリの CLOPT パラメータを使用して、UBBCONFIG ファイルで指定します。CLOPT パラメータには、システムで認識されるオプション、ダブル ハイフン (--)、アプリケーション固有のオプションの順に指定します。argc の値は、アプリケーション固有のオプションの数よりも 1 大きい値です。詳細については、『Oracle Tuxedo のファイル形式とデータ記述方法』の「ubbconfig(5)」を参照してください。
Server::initialize() で例外が発生すると、TP フレームワークがその例外を捕捉します。TP フレームワークは、initialize() が FALSE を返した場合と同じように動作します。つまり、例外は失敗と見なされます。また、エラー メッセージが、次のように例外型ごとにユーザ ログ (ULOG) ファイルに書き込まれます。
TobjS::InitializeFailed
"TPFW_CAT:1: ERROR: Server::initialize() で例外が発生しました: IDL:beasys.com/TobjS/InitializeFailed:1.0。Reason = reason。"
CORBA::Exception
その他の例外
サーバ初期化の最後のステップとして呼び出される initialize コールバック メソッドを使用すると、アプリケーションがアプリケーション固有の初期化を実行できます。
通常、サーバ アプリケーションは、Server::initialize で以下のタスクを実行します。
サーバ アプリケーションでは、必要な XA リソース マネージャを開く必要があります。この処理には、以下のいずれかのメソッドを呼び出します。
| 注意 : | INS ブートストラップ処理メカニズムを使用して初期オブジェクト参照を取得する場合は、TP::open_xa_rm() メソッドを使用する必要があります。 |
Tobj::TransactionCurrent::open_xa_rm()
TransactionCurrent オブジェクトのリファレンスは、Bootstrap オブジェクトから取得できます。Bootstrap オブジェクトのリファレンスの取得方法については、「TP::bootstrap()」を参照してください。TransactionCurrent オブジェクトの詳細については、「CORBA ブートストラップ処理のプログラミング リファレンス」と『Tuxedo CORBA トランザクション』を参照してください。 Tobj::TransactionCurrent::open_xa_rm() または TP::open_xa_rm メソッドの呼び出し後の initialize メソッドで開始できます。ただし、initialize() メソッドで開始したトランザクションは、initialize() が復帰する前に、サーバ アプリケーションで終了する必要があります。制御が戻ったときにトランザクションがアクティブな場合、サーバ アプリケーションが起動に失敗し、正常に終了します。これは、Server::initialize() が復帰した後にトランザクションをコミットするのかロールバックするのかを論理的に処理する方法がサーバ アプリケーションにないからです。この状況はエラーとなります。
Boolean の TRUE または FALSE。TRUE は成功を示します。FALSE は失敗を示します。initialize() でエラーが発生した場合、アプリケーション コードは FALSE を返します。アプリケーション コードでは、システム コールの exit() を呼び出してはなりません。exit() を呼び出すと、TP フレームワークが起動時に割り当てられたリソースを解放できないので、予期できない結果が発生する可能性があります。
Oracle Tuxedo ソフトウェアを使用して作成されたスレッドに対して、必要なアプリケーション固有の初期化を実行します。このメソッドは、マルチスレッド サーバ アプリケーションの開発をサポートします。
CORBA::Boolean thread_initialize(int argc, char** argv)argc
argv
スレッド プールを管理する場合、Oracle Tuxedo ソフトウェアでは、オペレーティング システムのスレッド ライブラリ サービスを使用してスレッドを作成および解放します。アプリケーションの要件によっては、要求を処理する前にこれらのスレッドを初期化する必要があります。
thread_initialize コールバック メソッドは、スレッドが作成されるたびに、スレッドの初期化を目的として呼び出されます。ただし、Oracle Tuxedo ソフトウェアでは、要求をディスパッチするために多数のシステム所有スレッドを管理しています。これらのスレッドも、スレッド プールに追加されます。状況によっては、ユーザが実装したサーバントのメソッドもこれらのシステム所有スレッドで実行されます。このため、Oracle Tuxedo ソフトウェアでは thread_initialize メソッドを呼び出して、システム所有のスレッドが初期化されます。
ServerBase クラスには、初期化されたスレッドで XA リソース マネージャを開く thread_initialize メソッドのデフォルト実装が用意されています。
CORBA::Boolean
CORBA::Boolean simple_per_request_server::thread_initialize(
int argc, char** argv)
{
TP::userlog("thread_initialize called in thread %ld",
(unsigned long)SIMPTHR_GETCURRENTTHREADID);
return CORBA_TRUE;
}
アプリケーションが、データベースからのログオフ、既知のファクトリの登録の削除、リソースの割り当て解除などのアプリケーション固有のクリーンアップを実行できるようにします。
typedef Tobj_ServantBase* Tobj_Servant;class Server {
public:
void release();
};
release() で例外が発生すると、TP フレームワークがその例外を捕捉します。例外が発生するたびに、エラー メッセージが、次のようにユーザ ログ (ULOG) ファイルに書き込まれます。
TobjS::ReleaseFailed
"TPFW_CAT:2: WARN: Server::release() で例外が発生しました: IDL:beasys.com/TobjS/ReleaseFailed:1.0。Reason = reason。"
CORBA::Exception
サーバ初期化の最初のステップとして呼び出される release コールバック メソッドを使用すると、アプリケーションがアプリケーション固有のクリーンアップを実行できます。ユーザは、仮想関数の定義を上書きしなければなりません。
このメソッドは通常、管理者またはオペレータからの tmshutdown コマンドに応答して呼び出されます。
TP フレームワークには、Server::release() のデフォルト実装が用意されています。デフォルト実装は、サーバ用の XA リソース マネージャを閉じます。この処理は、UBBCONFIG ファイルでサーバのグループに対してデフォルトとしてコンフィグレーションされている CLOSEINFO を使用する tx_close() 呼び出しによって行われます。
アプリケーションでは、開かれている XA リソース マネージャを閉じる必要があります。この処理には、以下のいずれかのメソッドを呼び出します。
| 注意 : | INS ブートストラップ処理メカニズムを使用して初期オブジェクト参照を取得する場合は、TP::close_xa_rm() メソッドを使用する必要があります。 |
Tobj::TransactionCurrent::close_xa_rm()。TransactionCurrent オブジェクトのリファレンスは、Bootstrap オブジェクトから取得できます。Bootstrap オブジェクトのリファレンスの取得方法については、「TP::bootstrap()」を参照してください。TransactionCurrent オブジェクトの詳細については、「CORBA ブートストラップ処理のプログラミング リファレンス」と『Tuxedo CORBA トランザクション』を参照してください。 | 注意 : | サーバが tmshutdown(1) コマンドから停止要求を受信すると、ほかのリモート オブジェクトからの要求を受信できなくなります。サーバを停止する場合、順序を考慮しなければならないことがあります。たとえば、サーバ 1 の Server::release() メソッドからサーバ 2 にあるオブジェクトのメソッドにアクセスする必要がある場合、サーバ 1 を停止してから、サーバ 2 を停止しなければなりません。特に、TP::unregister_factory() メソッドは、別のサーバにある FactoryFinder Registrar オブジェクトにアクセスします。通常、TP::unregister_factory() メソッドは release() メソッドから呼び出されるので、FactoryFinder サーバは、Server::release() メソッドで TP::unregister_factory() を呼び出すすべてのサーバの後に停止する必要があります。 |
Oracle Tuxedo ソフトウェアで作成されたスレッドが解放されたときに、アプリケーション固有のクリーンアップを実行します。このメソッドは、マルチスレッド サーバ アプリケーションの開発をサポートします。
void thread_release()
thread_release コールバック メソッドは、スレッドが解放されるたびに呼び出されます。アプリケーション固有のリソース クリーンアップを実行する場合は、thread_release を実装します。
ServerBase クラスには、解放されたスレッドの XA リソース マネージャを閉じる thread_release メソッドのデフォルト実装が用意されています。
void simple_per_request_server::thread_release()
{
TP::userlog("thread_release called in thread %ld",
(unsigned long)SIMPTHR_GETCURRENTTHREADID);
}
Tobj_ServantBase インタフェースは、PortableServer::RefCountServantBase クラスを継承し、スレッド セーフな方法で状態を管理する際に CORBA オブジェクトが役立つようにするオペレーションを定義します。IDL コンパイラによって生成される実装の各スケルトンは、Tobj_ServantBase クラスを自動的に継承します。Tobj_ServantBase クラスには、プログラマが任意で実装可能な 2 つの仮想メソッド (activate_object() および deactivate_object()) が含まれています。
アクティブ化されたいない CORBA オブジェクトに対する要求が受信されるたびに、オブジェクトがアクティブ化され、activate_object() メソッドがサーバントに対して呼び出されます。CORBA オブジェクトが非アクティブ化されると、deactivate_object() メソッドがサーバントに対して呼び出されます。非アクティブ化のタイミングは、実装のアクティブ化ポリシーによって決まります。deactivate_object() メソッドが呼び出されると、TP フレームワークは呼び出しの理由を示す理由コードを渡します。
これらのメソッドは、マルチスレッド サーバ アプリケーションの開発をサポートします。
| 注意 : | CORBA オブジェクトのアクティブ化および非アクティブ化時に呼び出すことを TP フレームワークで保証されているメソッドは、Tobj_ServantBase::activate_object() と Tobj_ServantBase::deactivate_object() だけです。アクティブ化および非アクティブ化時に C++ の Server::create_servant 呼び出しによってサーバント クラスのコンストラクタおよびデストラクタを呼び出すことはできません。したがって、サーバ アプリケーションでは、サーバント クラスのコンストラクタまたはデストラクタで CORBA オブジェクトの状態を処理してはなりません。 |
| 注意 : | プログラマは、直接 Tobj_ServantBase をキャストしたり、参照したりする必要がありません。Tobj_ServantBase メソッドはスケルトンに含まれているので、サーバントの実装にも含まれることになります。プログラマは activate_object および deactivate_object メソッドを定義できますが、これらのメソッドを直接呼び出してはなりません。TP フレームワークだけがこれらのメソッドを呼び出します。 |
次に、Tobj_servantBase インタフェースの C++ マッピングを示します。
class Tobj_ServantBase : public PortableServer::RefCountServantBase {
public:Tobj_ServantBase& operator=(const Tobj_ServantBase&);
Tobj_ServantBase() {}
Tobj_ServantBase(const Tobj_ServantBase& s) :
PortableServer::RefCountServantBase(s) {}
virtual void activate_object(const char *) {}virtual void deactivate_object(const char*,
TobjS::DeactivateReasonValue) {}
virtual CORBA::Boolean _is_reentrant() { return CORBA_FALSE; }
};typedef Tobj_ServantBase * Tobj_Servant;
オブジェクト ID をサーバントに関連付けます。このメソッドによって、アプリケーションでは、オブジェクトがアクティブ化されたときにオブジェクトの状態を復元できます。状態は、共有メモリ、通常のフラット ファイル、またはデータベース ファイルから復元できます。
class Tobj_ServantBase : public PortableServer::ServantBase {
public:
virtual void activate_object(const char * stroid) {}
};stroid
TP::create_object_reference() を使用してオブジェクト参照を作成したときに指定した ID、または TP::create_active_object_reference() の呼び出しで使用したオブジェクト参照の ID と同じになります。
| 注意 : | このリリースでは、オブジェクト ID の長さに関する制約がなくなりました。 |
オブジェクトのアクティブ化は、クライアントがアクティブ化されていない CORBA オブジェクトのメソッドを呼び出すことで開始されます。これにより、ポータブル オブジェクト アダプタ (POA) がサーバントを CORBA オブジェクトに割り当てます。activate_object() メソッドは、クライアントが呼び出したメソッドの前に呼び出されます。activate_object() から正常に制御が戻った場合、つまり例外が発生しなかった場合、要求されたメソッドがサーバントで実行されます。
プログラマは、activate_object() および deactivate_object() メソッドとクライアントが呼び出すメソッドを使用して、オブジェクトの状態を管理できます。これらのメソッドを使用してオブジェクトの状態を管理する方法は、アプリケーションのニーズによって異なります。これらのメソッドの使い方については、『Tuxedo CORBA サーバ アプリケーションの開発方法』を参照してください。
オブジェクトがグローバル トランザクションに関与している場合、activate_object() はそのグローバル トランザクションのスコープ内で実行されます。
オブジェクトのプログラマは、格納されているオブジェクトの状態が一貫性があるかどうかをチェックする必要があります。つまり、アプリケーション コードでは、deactivate_object() がオブジェクトの状態を正しく保存したかどうかを示す永続性フラグを保存する必要があります。このフラグを activate_object() でチェックします。
activate_object() の実行中にエラーが発生した場合、アプリケーション コードでは、CORBA 標準例外または TobjS::ActivateObjectFailed 例外を生成する必要があります。例外が発生すると、TP フレームワークは例外を捕捉して、以下のイベントが発生します。
| 注意 : | オペレーション呼び出しを受信したときにトランザクションを自動的に開始する場合、各 CORBA インタフェースに対して、AUTOTRAN を Yes に設定します。AUTOTRAN を Yes に設定しても、インタフェースが既にトランザクション モードにある場合は無効です。AUTOTRAN の詳細については、『Tuxedo CORBA トランザクション』を参照してください。 |
TobjS::ActivateObjectFailed
"TPFW_CAT:24: ERROR: オブジェクトの活性化時 - アプリケーションが TobjS::ActivateObjectFailed を上げました。Reason = reason。インタフェース = interfaceName、OID = oid。"
TobjS::OutOfMemory
"TPFW_CAT:22: ERROR: オブジェクトの起動時 - アプリケーションが例外 TobjS::OutOfMemory を上げました。Reason = reason。インタフェース = interfaceName、OID = oid。"
CORBA::Exception
"TPFW_CAT:25: ERROR: オブジェクトの活性化時 - CORBA の例外をアプリケーションが処理しませんでした。例外 ID = exceptionID。インタフェース = interfaceName、OID = oid。"
exceptionID は例外のインタフェース ID を示し、interfaceName と oid はそれぞれ呼び出された CORBA オブジェクトのインタフェース ID とオブジェクト ID を示します。
その他の例外
"TPFW_CAT:26: ERROR: オブジェクトの活性化時 - 不明な例外をアプリケーションが処理しませんでした。例外 ID = exceptionID。インタフェース = interfaceName、OID = oid。"
exceptionID は例外のインタフェース ID を示し、interfaceName と oid はそれぞれ呼び出された CORBA オブジェクトのインタフェース ID とオブジェクト ID を示します。
サーバントのリファレンスを追加します。このメソッドは、マルチスレッド サーバ アプリケーションの開発をサポートします。
| 注意 : | Oracle Tuxedo リリース 8.0 以降で作成するアプリケーションでは、TP::application_responsibility() メソッドの代わりにこのメソッドを使用します。 |
void _add_ref()
このメソッドは、サーバントのリファレンスが必要な場合に呼び出します。このメソッドを呼び出すと、サーバントのリファレンス数が 1 つインクリメントされます。
myServant * servant = new intf_i();if(servant != NULL)
servant->_add_ref();
オブジェクト ID とサーバントとの関連付けを削除します。このメソッドを使用すると、アプリケーションでは、オブジェクトが非アクティブ化される前にオブジェクトの状態のすべてまたは一部を保存できます。状態は、共有メモリ、通常のフラット ファイル、またはデータベース ファイルに保存できます。
class Tobj_ServantBase : public PortableServer::ServantBase {
public:
virtual void deactivate_object(const char* stroid,
TobjS::DeactivateReasonValue reason) {}
};stroid
| 注意 : | このリリースでは、オブジェクト ID の長さに関する制約がなくなりました。 |
reason
reason コードは、transaction アクティブ化ポリシーが設定されたオブジェクト専用です。これは、トランザクションがクライアントまたはシステムによって自動的に開始された場合に発生します。deactivate_object() メソッドがこの理由コードで呼び出された場合、トランザクションはロールバック対象としてマークされます。
reason コードは、transaction アクティブ化ポリシーが設定されたオブジェクト専用です。これは、トランザクションがクライアントまたは TP フレームワークによって開始された場合に発生します。これは、オブジェクトが呼び出されたトランザクションに対して Current.commit() オペレーションが呼び出されたことを示します。deactivate_object() メソッドは、トランザクション マネージャが 2 フェーズ コミット アルゴリズムを開始する直前、つまり prepare がリソース マネージャに送信される前に呼び出されます。
DR_TRANS_COMMITTING reason コードで deactivate_object() メソッドが呼び出されたときに、トランザクションの結果に関して判断できます。このメソッドは、Current.rollback_only() メソッドを呼び出すことで、トランザクションをロールバックさせることができます。そうでない場合は、2 フェーズ コミット アルゴリズムが続行されます。トランザクションは、Current.rollback_only() がこのメソッドで呼び出されなかったという理由以外でもコミットされないことがあります。トランザクションに関与するその他の CORBA オブジェクトまたはリソース マネージャも、トランザクションのロールバックを支持できます。
TP::deactivateEnable(-,-,-) を実行したためにオブジェクトが非アクティブ化されることを示します。これは、process アクティブ化ポリシーを設定されたオブジェクトに関してのみ発生します。
オブジェクトの非アクティブ化は、CORBA オブジェクトの実装に設定されているアクティブ化ポリシーに従って、システムまたはアプリケーションによって開始されます。deactivate_object() メソッドは、CORBA オブジェクトが非アクティブ化される前に呼び出されます。これらのポリシーおよび使い方については、「ICF の構文」を参照してください。
CORBA オブジェクトの実装のアクティブ化ポリシーが method の場合にクライアントによって呼び出されるメソッド、またはアクティブ化ポリシーが transaction の場合にトランザクションの処理が終わったときに呼び出されるメソッドの実行後に、非アクティブ化が発生する場合もあります。また、アクティブ化ポリシーが transaction または process の場合に、サーバが停止されると発生します。
さらに、Oracle Tuxedo ソフトウェアでは、process または method が設定された CORBA オブジェクトを、TP::deactivateEnable() および TP::deactivateEnable(-,-,-) メソッドによってユーザ側で制御して非アクティブ化することができます。TP::deactivateEnable をオブジェクトのメソッド内で呼び出すと、メソッドの終了時にそのオブジェクトが非アクティブ化されます。transaction アクティブ化ポリシーが設定されたオブジェクトで TP::deactivateEnable を呼び出すと、例外 (TobjS::IllegalOperation) が発生し、TP フレームワークは何の処理も行いません。process アクティブ化ポリシーが設定されたオブジェクトに対して TP::deactivateEnable(-,-,-) を呼び出すと、そのオブジェクトは非アクティブ化されます。詳細については、「TP::deactivateEnable()」を参照してください。
| 注意 : | サーバの停止時には、アクティブ オブジェクト マップに残っているすべてのオブジェクトに対して deactivate_object メソッドが呼び出されます。オブジェクトが AOM に追加される方法としては、TP フレームワークによって暗黙的に追加される場合 (オンデマンド アクティブ化手法。TP::create_servant とサーバントの activate_object メソッド) と、ユーザが TP::create_active_object_reference を使用して明示的に追加する方法があります。 |
プログラマは、activate_object() および deactivate_object() メソッドとクライアントが明示的に呼び出すメソッドを使用して、オブジェクトの状態を管理できます。これらのメソッドを使用してオブジェクトの状態を管理する方法は、アプリケーションのニーズによって異なります。これらのメソッドの使い方については、『Tuxedo CORBA サーバ アプリケーションの開発方法』を参照してください。
transaction アクティブ化ポリシーが設定された CORBA オブジェクトでは、DR_TRANS_COMMITTING 理由コードで deactivate_object() メソッドが呼び出されたときに、トランザクションの結果に関して判断できます。このメソッドは、Current.rollback_only() メソッドを呼び出すことで、トランザクションをロールバックさせることができます。そうでない場合は、2 フェーズ コミット アルゴリズムが続行されます。トランザクションは、Current.rollback_only() がこのメソッドで呼び出されなかったという理由以外でもコミットされないことがあります。トランザクションに関与するその他の CORBA オブジェクトまたはリソース マネージャも、トランザクションのロールバックを支持できます。
このメソッドが呼び出されたときにオブジェクトがトランザクションに関与している場合、オブジェクトが呼び出された理由に基づいて、実行可能な処理が制約されます。オブジェクトがトランザクションに関与していた場合、アクティブ化ポリシーが transaction で、呼び出しの reason コードは以下のいずれかです。
DR_TRANS_ABORTED
DR_TRANS_COMMITTING
こうした制約がある理由は、トランザクション バウンドのアクティブ化ポリシーを設定されたオブジェクトの非アクティブ化が、トランザクションのトランザクション マネージャから TP フレームワークに対する呼び出しによって制御されるからです。reason コード DR_TRANS_COMMITTING で呼び出しが行われた場合、トランザクション マネージャは 2 フェーズ コミットのフェーズ 1 (準備) を実行しています。この段階では、トランザクションを一時停止する呼び出し、または新しいトランザクションを開始する呼び出しを行うことはできません。別のプロセス内の CORBA オブジェクトを呼び出すにはそのプロセスがトランザクションに参加する必要があり、トランザクション マネージャは既に準備フェーズを実行しているので、この呼び出しを行うとエラーが発生します 1。トランザクションに関与していない CORBA オブジェクトを呼び出すには、そのトランザクションを一時停止する必要があるので、これもエラーの原因となります。同じことは tpcall() にもあてはまります。
同じように、reason コード DR_TRANS_ABORTED での呼び出しが行われた場合、トランザクション マネージャは既にアボート中です。トランザクション マネージャがアボート中の場合、トランザクションを一時停止したり、新しいトランザクションを開始したりすることはできません。この制約は、DR_TRANS_COMMITTING に関しても適用されます。
クライアントによって呼び出される CORBA オブジェクト メソッドで例外が発生した場合、TP フレームワークが例外を捕捉して、最終的にクライアントに返します。これは、deactivate_object() を呼び出して例外が発生した場合にもあてはまります。
クライアントには、deactivate_object() で発生した例外について通知されません。アプリケーション コードでは、格納されている CORBA オブジェクトの状態が一貫性があるかどうかをチェックする必要があります。たとえば、アプリケーション コードで、deactivate_object() がオブジェクトの状態を正しく保存したかどうかを示す永続性フラグを保存すると便利です。このフラグを activate_object() でチェックします。
deactivate_object() の実行中にエラーが発生した場合、アプリケーション コードでは、CORBA 標準例外または DeactivateObjectFailed 例外を生成する必要があります。deactivate_object() が TP フレームワークで呼び出されると、TP フレームワークは例外を捕捉して、以下のイベントが発生します。
TobjS::DeactivateObjectFailed
"TPFW_CAT:27: ERROR: オブジェクトの非活性化時 - アプリケーションが TobjS::DeactivateObjectFailed を上げました。Reason = reason。インタフェース = interfaceName、OID = oid。"
CORBA::Exception
"TPFW_CAT:28: ERROR: オブジェクトの非活性化時 - CORBA の例外をアプリケーションが処理しませんでした。例外 ID = exceptionID。インタフェース = interfaceName、OID = oid。"
exceptionID は例外のインタフェース ID を示し、interfaceName と oid はそれぞれ呼び出された CORBA オブジェクトのインタフェース ID とオブジェクト ID を示します。
その他の例外
"TPFW_CAT:29: ERROR: オブジェクトの非活性化時 - 不明な例外をアプリケーションが処理しませんでした。例外 ID = exceptionID。インタフェース = interfaceName、OID = oid。"
exceptionID は例外のインタフェース ID を示し、interfaceName と oid はそれぞれ呼び出された CORBA オブジェクトのインタフェース ID とオブジェクト ID を示します。
オブジェクトが同時リエントラント呼び出しをサポートしていることを示します。このメソッドは、マルチスレッド サーバ アプリケーションの開発をサポートします。
CORBA::Boolean_is_reentrant()
Oracle Tuxedo サーバ インフラストラクチャでは、このメソッドを使用して、サーバント実装がリエントラント呼び出しをサポートしているかどうかを判断します。リエントラントをサポートするには、複数のスレッドがオブジェクトと対話する場合に状態の整合性を保護するためのコードをサーバントに含める必要があります。
Tobj_ServantBase クラスには、FALSE を返す _is_reentrant メソッドのデフォルト実装が用意されています。
CORBA::Boolean
CORBA::Boolean Simple_i::_is_reentrant()
{ TP::userlog("_is_reentrant called in thread %ld",
(unsigned long)SIMPTHR_GETCURRENTTHREADID);
return CORBA_TRUE;
}
サーバントのリファレンスを解放します。このメソッドは、マルチスレッド サーバ アプリケーションの開発をサポートします。
| 注意 : | Oracle Tuxedo リリース 8.0 以降で作成するアプリケーションでは、TP::application_responsibility() メソッドで使用していた C++ の「delete」文の代わりに、このメソッドを使用します。 |
void _remove_ref()
このメソッドは、サーバントのリファレンスが必要でなくなった場合に呼び出します。このメソッドを呼び出すと、サーバントのリファレンス数が 1 つ減ります。_remove_ref() メソッドによってリファレンス数がゼロになると、このメソッドは自身の this ポインタに対して C++ の「delete」文を呼び出し、サーバントを「削除」します。
if(servant != NULL)
servant->_remove_ref();
TP インタフェースでは、アプリケーション コードで呼び出せるサービス メソッドのセットが提供されます。これは、アプリケーション コードで安全に呼び出せる TP フレームワーク内の唯一のインタフェースです。その他のインタフェースは、システム コードでのみ呼び出すことを目的としたコールバック メソッドを持っています。
このインタフェースの目的は、ポータブル オブジェクト アダプタ (POA)、CORBA ネーミング サービス、および Oracle Tuxedo システムで提供される基底の API に対する呼び出しの代わりに、アプリケーション コードで呼び出し可能な高レベルの呼び出しを行えるようにすることです。これらの呼び出しにより、プログラマはより簡単な API を使用できるので、複雑な基底 API を使用せずに済みます。TP インタフェースでは、CORBA API を拡張した Oracle Tuxedo ソフトウェアの以下の 2 つの機能を暗黙的に使用します。
FactoryFinder オブジェクトの詳細については、「FactoryFinder インタフェース」を参照してください。ファクトリ ベース ルーティングの詳細については、『Oracle Tuxedo アプリケーションの設定』を参照してください。
class TP {const char* interfaceName,
public:
static CORBA::Object_ptr create_object_reference(
const char* stroid,
CORBA::NVList_ptr criteria);
static CORBA::Object_ptr create_active_object_reference(
const char* interfaceName,
const char* stroid,
Tobj_Servant servant);
static CORBA::Object_ptr get_object_reference();
static void register_factory(
CORBA::Object_ptr factory_or,
const char* factory_id);
static void unregister_factory(
CORBA::Object_ptr factory_or,
const char* factory_id);
static void deactivateEnable()
static void deactivateEnable(
const char* interfaceName,
const char* stroid,
Tobj_Servant servant);
static CORBA::ORB_ptr orb();
static Tobj_Bootstrap* bootstrap();
static void open_xa_rm();
static void close_xa_rm();
static int userlog(char*, ...);
static char* get_object_id(CORBA::Object_ptr obj);
static void application_responsibility(
Tobj_Servant servant);
};
アプリケーションがサーバントの有効期間を管理することを TP フレームワークに通知します。
| 注意 : | Oracle Tuxedo リリース 8.0 以上で作成するアプリケーションではこのメソッドを使用しないでください。代わりに、Tobj_ServantBase::_add_ref() メソッドを使用します。 |
static void application_responsibility(Tobj_Servant servant);servant
TobjS::InvalidServant
このメソッドは、アプリケーションがサーバントの有効期間を制御することを TP フレームワークに通知します。このメソッドを呼び出すと、TP フレームワークがオブジェクトを非アクティブ化した後に、つまりサーバントの deactivate_object メソッドを呼び出した後に、オブジェクトに対して何の処理も行われません。
サーバントをアプリケーション側で処理する場合、その他の C++ インスタンスと同じように、不要になった時点でサーバントを削除しなければなりません。
サーバントが TP フレームワークに認識されていない (アクティブ化されていない) 場合、この呼び出しは無効です。
Tobj::Tobj_Bootstrap オブジェクトに対するポインタを返します。Bootstrap オブジェクトは、FactoryFinder オブジェクト、インタフェース リポジトリ、TransactionCurrent オブジェクト、および SecurityCurrent オブジェクトへの初期リファレンスにアクセスする場合に使用します。
static Tobj_Bootstrap* TP::bootstrap();
bootstrap() は、正常に終了すると、サーバ アプリケーションの開始時に TP フレームワークで作成された Tobj::Tobj_Bootstrap オブジェクトに対するポインタを返します。
TP フレームワークでは、初期化の一部として Tobj::Tobj_Bootstrap オブジェクトが作成されます。したがって、アプリケーション コードでほかの Tobj::Tobj_Bootstrap オブジェクトをサーバ内に作成する必要はありません。
| 注意 : | Tobj::Tobj_Bootstrap オブジェクトの所有権は TP フレームワークにあるので、サーバ アプリケーション コードで Bootstrap オブジェクトを破棄してはなりません。 |
| 注意 : | CORBA INS ブートストラップ処理メカニズムを使用し、セキュリティ用の SecurityCurrent またはトランザクション用の TransactionCurrent を使用しない場合は、Bootstrap オブジェクトを使用する必要はありません。 |
呼び出しプロセスのリンク先の XA リソース マネージャを閉じます。
static void TP::close_xa_rm ();
close_xa_rm() メソッドは、呼び出しプロセスのリンク先の XA リソース マネージャを閉じます。XA リソース マネージャは、Oracle や Informix などのデータベース ベンダから提供されます。
| 注意 : | この呼び出しの機能も、Tobj::TransactionCurrent::close_xa_rm() によって提供されます。TransactionCurrent オブジェクトのオブジェクト参照を取得する必要がないので、サーバ アプリケーションでリソース マネージャを閉じる方法としては、TP::close_xa_rm() メソッドを使う方がはるかに便利です。TransactionCurrent オブジェクトのリファレンスは、Bootstrap オブジェクトから取得できます。Bootstrap オブジェクトのリファレンスの取得方法については、「TP::bootstrap()」を参照してください。TransactionCurrent オブジェクトの詳細については、「CORBA ブートストラップ処理のプログラミング リファレンス」と『Tuxedo CORBA トランザクション』を参照してください。 |
グローバル トランザクションに関与するサーバごとに Server::release() メソッドから 1 回、このメソッドを呼び出す必要があります。グローバル トランザクションに関与しているすべてのサーバだけでなく、XA リソース マネージャにリンクされたサーバも含まれますが、XA 準拠のリソース マネージャに実際にはリンクされていません。
close_xa_rm() メソッドは、リソース マネージャに固有のクローズ呼び出しの代わりに呼び出します。リソース マネージャの初期化セマンティクスはそれぞれ異なるので、特定のリソース マネージャを閉じるための情報を、Oracle Tuxedo システムの UBBCONFIG ファイルの GROUPS セクションにある CLOSEINFO パラメータに指定します。
CLOSEINFO 文字列の形式は、基底のリソース マネージャのデータベース ベンダごとに異なります。CLOSEINFO パラメータの詳細については、『Oracle Tuxedo アプリケーションの設定』と『Oracle Tuxedo のファイル形式とデータ記述方法』の「ubbconfig(5)」のリファレンス ページを参照してください。また、XA ライブラリを使用するアプリケーションの開発およびインストール方法については、データベース ベンダのマニュアルを参照してください。
CORBA::BAD_INV_ORDER
Tobj::RMFailed
| 注意 : | TP フレームワークのその他の例外と違い、Tobj::RMFailed 例外は、TobjS_c.h (TobjS.idl から派生) ではなく、tobj_c.h (tobj.idl から派生) で定義されます。これは、ネイティブ クライアントでも XA リソース マネージャを開けるからです。したがって、返される例外は、ネイティブ クライアント コードおよび Server::release() (ネイティブ クライアントと共有される代替メカニズムである TransactionCurrent::close_xa_rm を使用している場合) で想定される例外と一致します。 |
オブジェクト参照を作成し、オブジェクトを事前アクティブ化します。
static CORBA::Object_ptr
create_active_object_reference(
const char* interfaceName,
const char* stroid,
Tobj_Servant servant);interfaceName
stroid
ObjectId を文字列形式で指定します。ObjectId は、クラスのこのインスタンスをユニークに識別します。プログラマは、ObjectId に指定する情報を決めます。一例として、データベース キーの保持に使用する方法があります。オブジェクト識別子の値を選択、つまりユニーク性のレベルを決定することは、アプリケーション デザインの一環です。Oracle Tuxedo ソフトウェアでは、オブジェクト参照のユニーク性は保証されません。オブジェクト参照を文字列化する場合など、オブジェクト参照をコピーしたり、Oracle Tuxedo 環境の外で共有したりすることがあるからです。
servant
TobjS::InvalidInterface
TobjS::InvalidObjectId
TobjS::ServantAlreadyActive
ObjectId で使用されているので、オブジェクトを明示的にアクティブ化することができませんでした。サーバントは、1 つの ObjectId でのみ使用できます。異なる ObjectId を持つオブジェクトを事前アクティブ化するには、アプリケーションで複数のサーバントを作成し、ObjectId ごとに個別に事前アクティブ化する必要があります。
TobjS::ObjectAlreadyActive
ObjectId が既にアクティブ オブジェクト マップで使用されているので、オブジェクトを明示的にアクティブ化することができませんでした。ある特定の ObjectId には、1 つのサーバントしか関連付けられません。別のサーバントに変更するには、アプリケーションでまずオブジェクトを事前アクティブ化してからもう一度アクティブ化する必要があります。
TobjS::IllegalOperation
このメソッドでは、オブジェクト参照を作成し、オブジェクトを事前アクティブ化します。作成されたオブジェクト参照は、オブジェクトへのアクセスで使用するクライアントに渡されます。
通常、アプリケーションではこのメソッドを以下の 2 か所で呼び出します。
このメソッドを使用すると、アプリケーションでは最初の呼び出しの前にオブジェクトをアクティブ化できます。この処理が有用となる理由については、「明示的なアクティブ化」を参照してください。ユーザはまずサーバントを作成し、状態を設定してから、create_active_object_reference を呼び出します。TP フレームワークでは、サーバントおよび ObjectId 文字列をアクティブ オブジェクト マップに入れます。その結果、TP フレームワークで既に Server::create_servant を呼び出し、サーバント ポインタを受け取ってから、servant::activate_object を呼び出した場合とまったく同じ状態になります。
アクティブ化されたオブジェクトは、プロセス バウンド アクティブ化ポリシーで宣言されたインタフェース用でなければなりません。それ以外の場合、例外が発生します。
オブジェクトを非アクティブ化すると、クライアントで保持されていたオブジェクト参照を使用して、そのオブジェクトをほかのプロセスでアクティブ化することができます。この処理が問題となる状況については、「明示的なアクティブ化」を参照してください。
| 注意 : | ユーザ制御の同時実行性ポリシー オプションが ICF ファイルで設定されている場合、このメソッドに関する制約が 1 つあります (「パラレル オブジェクト」を参照してください)。TP::create_active_object_reference メソッドは、ユーザ制御の同時実行性が設定されたインタフェースを渡されると、TobjS::IllegalOperation 例外を送出します。AOM はユーザ制御の同時実行性が設定されている場合に使用されないので、TP フレームワークにはアクティブ化されたオブジェクトをこのサーバに接続する方法がありません。 |
インタフェースのオブジェクトを事前アクティブ化する場合、そのインタフェースの ICF ファイルで process アクティブ化ポリシーを指定する必要があります。ただし、ICF ファイルで process アクティブ化ポリシーを指定すると、次の問題が発生する可能性があります。
activate_object メソッドを記述して、ActivateObjectFailed 例外が送出されるようにします。activate_object メソッドが ActivateObjectFailed 例外を送出するため、SERVER1 ではインタフェース A のオブジェクトをアクティブ化できません。
この問題を防ぐには、管理者が SERVER1 と SERVER2 をそれぞれ別のグループとしてコンフィグレーションします。グループを定義するには、UBBCONFIG ファイルの SERVERS セクションを使用します。
オブジェクト参照を作成します。作成されたオブジェクト参照は、オブジェクトへのアクセスで使用するクライアントに渡されます。
static CORBA::Object_ptr TP::create_object_reference (char*
const char* interfaceName,
conststroid,
CORBA::NVList_ptr criteria);
interfaceName
const char* _tc_<CORBA interface name>::id();
CORBA interface name は任意のオブジェクト クラス名です。次に例を示します。
char* idlname = _tc_Simple->id();
stroid
ObjectId を文字列形式で指定します。ObjectId は、クラスのこのインスタンスをユニークに識別します。プログラマは、ObjectId に指定する情報を決めます。一例として、ObjectId でデータベース キーを保持する方法があります。オブジェクト識別子の値を選択、つまりユニーク性のレベルを決定することは、アプリケーション デザインの一環です。Oracle Tuxedo ソフトウェアでは、オブジェクト参照のユニーク性は保証されません。オブジェクト参照を文字列として渡す場合など、オブジェクト参照をコピーしたり、Oracle Tuxedo ドメインの外で共有したりすることがあるからです。オブジェクト参照に対して複数の呼び出しを並列実行できるように、ObjectId をユニークに指定することをお勧めします。
| 注意 : | このリリースでは、ObjectId の長さに関する制約がなくなりました。 |
criteria
CORBA::NVList 型です。ファクトリ ベース ルーティングを使用するかどうかは任意で、使用する場合はこの引数に依存します。ファクトリ ベース ルーティングを使用しない場合は、この引数に 0 (ゼロ) を渡します。
UBBCONFIG ファイルでルーティング規則を指定して、ファクトリ ベース ルーティングをコンフィグレーションします。この機能の詳細については、オンライン マニュアルの『Oracle Tuxedo アプリケーションの設定』を参照してください。
create_object_reference() メソッドの例外は以下のとおりです。
InvalidInterface
InvalidObjectId
create_object_reference() メソッドの呼び出しは、サーバ アプリケーションの役割です。このメソッドによって、オブジェクト参照が作成されます。作成されたオブジェクト参照は、オブジェクトへのアクセスで使用するクライアントに渡されます。
通常、サーバ アプリケーションではこのメソッドを以下の 2 か所で呼び出します。
create_object_reference() メソッドの呼び出し方法とタイミングの例については、『Tuxedo CORBA サーバ アプリケーションの開発方法』を参照してください。
Object
次のサンプル コードは、criteria 引数の使用方法を示しています。
CORBA::NVList_ptr criteria;
CORBA::Long branch_id = 7;
CORBA::Long account_id = 10001;
CORBA::Any any_val;// リストを作成して _var に割り当てて、終了時にクリーンアップ
CORBA::ORB::create_list (2, criteria);
CORBA::NVList_var criteria_var(criteria);// BRANCH_ID を追加
any_val <<= branch_id;
criteria->add_value("BRANCH_ID", any_val, 0);// ACCOUNT_ID を追加
any_val <<= account_id;
criteria->add_value("ACCOUNT_ID", any_val, 0);// オブジェクト参照を作成
TP::create_object_reference ("IDL:BankApp/Teller:1.0",
"Teller_01", criteria);
CORBA オブジェクトのアプリケーション制御の非アクティブ化を有効にします。
static void TP::deactivateEnable();static void TP::deactivateEnable(
const char* interfaceName,
const char* stroid,
Tobj_Servant servant);
interfaceName
stroid
servant
deactivateEnable() メソッドの例外は以下のとおりです。
IllegalOperation
TobjS::ObjectNotActive
stroid および servant パラメータはアクティブ オブジェクト マップ内でオブジェクトを識別できなかったので、アクティブ化できませんでした。
このオブジェクトを使用すると、同時実行されているオブジェクト (オブジェクトを呼び出したメソッドの終了時)、または別のオブジェクトを非アクティブ化できます。このメソッドは、プロセス バウンド アクティブ化ポリシーが設定されたオブジェクトに対してのみ使用できます。このメソッドにより、process アクティブ化ポリシーが設定されたオブジェクトをさらに柔軟に扱うことができます。
| 注意 : | シングル スレッド サーバの場合、TP::deactivateEnable(interface, object id, servant) メソッドを使用すると、オブジェクトを非アクティブ化できます。ただし、オブジェクトがトランザクションに参加している場合、オブジェクトが非アクティブ化されるのは、トランザクションがコミットまたはロールバックしたときです。トランザクションがコミットまたはロールバックする前にオブジェクトに対して呼び出しが行われた場合、オブジェクトは非アクティブ化されません。 |
| 注意 : | 必要な動作が確実に実行されるようにするには、オブジェクトがトランザクションに参加していないことを確認するか、TP::deactivateEnable() を呼び出してからトランザクションが終了するまでオブジェクトに対して呼び出しが行われないようにします。 |
| 注意 : | マルチスレッド サーバの場合、TP::deactivateEnable(interface, object id, servant) メソッドを使用して、オブジェクトごとのサーバのオブジェクトを非アクティブ化することはできません。このメソッドでは、要求ごとのサーバのオブジェクトを非アクティブ化することができますが、ほかのスレッドがオブジェクトを操作しているので、非アクティブ化は延期されます。 |
呼び出されるオーバーロード関数の種類によって、操作は次のようになります。
DR_METHOD_END を使用して、オブジェクトに関連付けられたサーバントの deactivate_object メソッドが呼び出されます。
ObjectId と関連付けられたサーバントを指定することで、オブジェクトの非アクティブ化を要求します。
DR_EXPLICIT_DEACTIVATE を使用して、オブジェクトに関連付けられたサーバントの deactivate_object メソッドが呼び出されます。
非アクティブ化を要求されたオブジェクトに transaction アクティブ化ポリシーが設定されていた場合、IllegalOperation 例外が発生します。これは、こうしたオブジェクトを非アクティブ化すると、Oracle Tuxedo トランザクション マネージャからのトランザクション終了の通知と競合する場合があるからです。
サーバが、TP フレームワークで作成されたオブジェクト参照から ObjectId 文字列を取り出せるようにします。
char* TP::get_object_id(Corba::Object_ptr obj);TobjS::InvalidObject
このメソッドを使用すると、サーバが、TP フレームワークで作成されたオブジェクト参照から ObjectId 文字列を取り出せます。オブジェクト参照がクライアント ORB などによって作成され、TP フレームワークで作成されていない場合、例外が発生します。
呼び出し側では、オブジェクト参照が不要になった場合に、戻り値に対して CORBA::string_free を呼び出す必要があります。
オブジェクト参照の作成時に TP::create_object_reference または TP::create_active_object_reference に渡された ObjectId 文字列。
static CORBA::Object_ptr TP::get_object_reference ();
get_object_reference() が Server::initialize() または Server::release() 内から呼び出された場合、アプリケーションの TP オブジェクトの実行スコープ外で呼び出されたものと見なされるので、TobjS::NilObject 例外が発生します。
get_object_reference() メソッドの例外は次のとおりです。
NilObject
このメソッドは、現在のオブジェクトへのポインタを返します。返された CORBA::Object_ptr ポインタは、クライアントに渡すことができます。
CORBA オブジェクトの実行スコープ内で呼び出された場合、get_object_reference() メソッドは、現在のオブジェクトの CORBA::Object_ptr を返します。それ以外の場合、TobjS::NilObject 例外が発生します。
呼び出しプロセスのリンク先の XA リソース マネージャを開きます。
static void TP::open_xa_rm();Tobj::RMFailed
tx_open() 呼び出しによって、エラー戻りコードが返されました。
| 注意 : | TP フレームワークのその他の例外と違い、この例外は、TobjS_c.h (TobjS.idl から派生) ではなく、tobj_c.h (tobj.idl から派生) で定義されます。これは、ネイティブ クライアントでも XA リソース マネージャを開けるからです。したがって、返される例外は、ネイティブ クライアント コードおよび Server::release() (ネイティブ クライアントと共有される代替メカニズムである TransactionCurrent::close_xa_rm を使用している場合) で想定される例外と一致します。 |
open_xa_rm() メソッドは、呼び出しプロセスのリンク先の XA リソース マネージャを開きます。XA リソース マネージャは、Oracle や Informix などのデータベース ベンダから提供されます。
| 注意 : | このメソッドの機能も、Tobj::TransactionCurrent::close_xa_rm() によって提供されます。ただし、TransactionCurrent オブジェクトのオブジェクト参照を取得する必要がないので、サーバ アプリケーションでリソース マネージャを開く方法としては、TP::open_xa_rm() メソッドを使う方がはるかに便利です。TransactionCurrent オブジェクトのリファレンスは、Bootstrap オブジェクトから取得できます。Bootstrap オブジェクトのリファレンスの取得方法については、「TP::bootstrap()」を参照してください。TransactionCurrent オブジェクトの詳細については、「CORBA ブートストラップ処理のプログラミング リファレンス」と『Tuxedo CORBA トランザクション』を参照してください。 |
グローバル トランザクションに関与するサーバごとに Server::initialize() メソッドから 1 回、このメソッドを呼び出す必要があります。グローバル トランザクションに関与しているすべてのサーバだけでなく、XA リソース マネージャにリンクされたサーバも含まれますが、XA 準拠のリソース マネージャに実際にはリンクされていません。
open_xa_rm() メソッドは、リソース マネージャに固有のオープン呼び出しの代わりに呼び出します。リソース マネージャの初期化セマンティクスはそれぞれ異なるので、特定のリソース マネージャを開くための情報を、UBBCONFIG ファイルの GROUPS セクションにある OPENINFO パラメータに指定します。
OPENINFO 文字列の形式は、基底のリソース マネージャのデータベース ベンダごとに異なります。CLOSEINFO パラメータの詳細については、『Oracle Tuxedo アプリケーションの設定』と『Oracle Tuxedo のファイル形式とデータ記述方法』の「ubbconfig(5)」のリファレンス ページを参照してください。また、XA ライブラリを使用するアプリケーションの開発およびインストール方法については、データベース ベンダのマニュアルを参照してください。
| 注意 : | 呼び出しプロセスにリンクできるリソース マネージャは 1 つだけです。 |
static CORBA::ORB_ptr TP::orb();
ORB オブジェクトにアクセスすると、アプリケーションでは、string_to_object() や object_to_string() などの ORB オペレーションを呼び出すことができます。
| 注意 : | TP フレームワークが ORB オブジェクトを所有しているので、アプリケーションが削除してはなりません。 |
orb() は、正常に終了すると、サーバ プログラムの開始時に TP フレームワークで作成された ORB オブジェクトに対するポインタを返します。
Oracle Tuxedo FactoryFinder オブジェクトを見つけて、Oracle Tuxedo ファクトリに登録します。
static voidTP::register_factory(
CORBA::Object_ptr factory_or, const char* factory_id);
factory_or
factory_id
register_factory() メソッドの例外は以下のとおりです。
TobjS::CannotProceed
ULOG) に書き込まれます。この例外が発生した場合は、すぐに作業担当者に通知してください。内部エラーの重要度によっては、FactoryFinder または NameManager が実行されていたサーバが終了していることがあります。FactoryFinder サービスが終了した場合は、新しい FactoryFinder サービスを開始します。NameManager が終了しており、別の NameManager が実行中である場合は、新規の NameManager を開始します。稼動中の NameManager がない場合は、アプリケーションを再起動します。
TobjS::InvalidName
TobjS::InvalidObject
TobjS::RegistrarNotAvailable
| 注意 : | その他、FactoryFinder がトランザクションに関与できない場合にも、この例外が発生する場合があります。したがって、TP::register_factory() および TP::unregister_factory() 呼び出しの前に、現在のトランザクションを一時停止しなければならない場合があります。トランザクションの一時停止と再開方法については、オンライン マニュアルの『Tuxedo CORBA トランザクション』を参照してください。 |
TobjS::OverFlow
このメソッドでは、Oracle Tuxedo FactoryFinder オブジェクトを見つけて、Oracle Tuxedo ファクトリに登録します。通常、TP::register_factory() は、サーバがファクトリを作成するときに、Server::initialize() から呼び出します。register_factory() メソッドでは、Oracle Tuxedo FactoryFinder オブジェクトを見つけて、Oracle Tuxedo ファクトリに登録します。
| 注意 : | コールバック オブジェクト (つまり、POA を介して共同クライアント/サーバによって直接作成されるオブジェクト) を FactoryFinder に登録してはなりません。 |
Oracle Tuxedo FactoryFinder オブジェクトを見つけて、ファクトリを削除します。
static voidTP::unregister_factory(
CORBA::Object_ptr factory_or, const char* factory_id);
factory_or
factory_id
unregister_factory() メソッドの例外は以下のとおりです。
CannotProceed
ULOG) に書き込まれます。この例外が発生した場合は、すぐに作業担当者に通知してください。内部エラーの重要度によっては、FactoryFinder または NameManager が実行されていたサーバが終了していることがあります。FactoryFinder サービスが終了した場合は、新しい FactoryFinder サービスを開始します。NameManager が終了しており、別の NameManager が実行中である場合は、新規の NameManager を開始します。稼動中の NameManager がない場合は、アプリケーションを再起動します。
InvalidName
RegistrarNotAvailable
| 注意 : | その他、FactoryFinder がトランザクションに関与できない場合にも、この例外が発生する場合があります。したがって、TP::register_factory() および TP::unregister_factory() 呼び出しの前に、現在のトランザクションを一時停止しなければならない場合があります。トランザクションの一時停止と再開方法については、オンライン マニュアルの『Tuxedo CORBA トランザクション』を参照してください。 |
TobjS::OverFlow
このメソッドでは、Oracle Tuxedo FactoryFinder オブジェクトを見つけて、ファクトリを削除します。通常、TP::unregister_factory() は、サービス ファクトリの登録を削除するために Server::release() から呼び出されます。
ユーザ ログ (ULOG) ファイルにメッセージを書き込みます。
static int TP::userlog(char*, ...);
最初の引数では、printf(3S) スタイルの形式を指定します。printf(3S) 引数については、C または C++ リファレンス マニュアルで説明されています。
userlog() メソッドは、ユーザ ログ (ULOG) ファイルにメッセージを書き込みます。メッセージは、時刻 (hhmmss)、システム名、プロセス名、および呼び出しプロセスのプロセス ID で構成されるタグを付けて、ULOG ファイルに追加されます。タグの最後にはコロンが付けられます。
サーバ アプリケーションでは、userlog() によるメッセージをアプリケーション エラーのデバッグで有用となるメッセージに限定することをお勧めします。ULOG が重要度の低いメッセージでいっぱいになると、実際のエラーの特定が難しくなります。
userlog() メソッドは、出力された文字数を返し、出力エラーが発生した場合には、負の値を返します。出力エラーには、現在のログ ファイルのオープン エラーや書き込みエラーがあります。
次のサンプル コードは、TP::userlog() メソッドの使用方法を示しています。
userlog (“System exception caught: %s”, e.get_id());
このインタフェースの使用は避けてください。このインタフェースの使用は任意となったので、トランザクションに関与するオブジェクトに対して、このインタフェースの下位インタフェースを使用する必要はありません。プログラマは、never または ignore トランザクション ポリシーを指定して、オブジェクトがトランザクションに関与しないように指定できます。トランザクションの処理にインタフェースを使用する必要はありません。指定するのはトランザクション ポリシーだけです。
| 注意 : | CORBA サービス オブジェクト トランザクション サービスでは、すべての要求をトランザクションのスコープ内で実行する必要はありません。トランザクションのスコープ外で呼び出された場合の動作は各オブジェクトで決定します。トランザクション コンテキストを必要とするオブジェクトは、標準例外を生成する場合があります。 |
TP フレームワークでは以下の例外が発生します。発生した例外は、エラーが発生したクライアントに返されるか、TP で検出されます。
CORBA::INTERNAL
CORBA::OBJECT_NOT_EXIST
CORBA::OBJ_ADAPTER
CORBA::INVALID_TRANSACTION
CORBA::TRANSACTION_ROLLEDBACK
これらの例外の理由は明確ではないので、TP フレームワークでは、例外が発生するたびに、理由を示すエラー メッセージがユーザ ログ ファイルに書き込まれます。
クライアントによって呼び出されたメソッド内で発生した例外は、クライアントによって呼び出されたメソッドで発生した例外と同じように、クライアントに返されます。
TP フレームワークの以下のコールバック メソッドは、オブジェクトに対するクライアントの要求以外のイベントによって開始されます。
Tobj_ServantBase::activate_object()
Tobj_ServantBase::deactivate_object()
Server::create_servant()
これらのメソッドで例外が発生した場合、まったく同じ例外がクライアントに通知されるわけではありません。ただし、これらの各メソッドは、reason 文字列を含む例外を生成するように定義されています。TP フレームワークでは、コールバックによって生成された例外が捕捉され、reason 文字列がユーザ ログ ファイルに書き込まれます。TP フレームワークでは、クライアントに例外を返すこともできます。これらの例外の詳細については、TP フレームワークの各コールバック メソッドの説明を参照してください。
Tobj_ServantBase::deactivate_object() の場合、次のコードは DeactivateObjectFailed 例外を送出します。
throw TobjS::DeactivateObjectFailed( “deactivate failed to save
state!”);
このメッセージは、時刻 (hhmmss)、システム名、プロセス名、および呼び出しプロセスのプロセス ID で構成されるタグを付けて、ユーザ ログ ファイルに追加されます。タグの最後にはコロンが付けられます。上記の throw 文によって、次の行がユーザ ログ ファイルに書き込まれます。
151104.T1!simpapps.247: APPEXC: deactivate failed to save state!
151104 は時刻 (3:11:04pm)、T1 はシステム名、simpapps はプロセス名、247 はプロセス ID をそれぞれ示し、APPEXC はメッセージがアプリケーション例外メッセージであることを示します。
CORBA オブジェクト メソッドまたは TP フレームワークのコールバック メソッドで例外が発生しても、TP フレームワークがトランザクションを開始していない限り、トランザクションは自動的にはロールバックされません。例外が発生した条件に基づいてトランザクションをロールバックする場合は、アプリケーション コードで Current.rollback_only() を呼び出す必要があります。
TP フレームワークには、CORBA オブジェクトに対するネストされた呼び出しに関して制約があります。制約の内容は次のとおりです。
TP フレームワークでは、別の CORBA オブジェクトが既にメソッド呼び出しを処理しているオブジェクトのクライアントとして機能していることを検出すると、呼び出し側に CORBA::OBJ_ADAPTER 例外を返します。
| 注意 : | アプリケーション コードではこの動作に依存しないようにしてください。つまり、ユーザはこの動作が発生することを前提に処理を行わないでください。この制限は、今後のリリースで取り払われます。 |
1 理論上は、同じプロセスのトランザクション CORBA オブジェクトに対する呼び出しは、新しいプロセスをトランザクション マネージャに登録する必要がないため、有効となります。ただし、CORBA オブジェクトに対する呼び出しがプロセスで発生するようにプログラミングすることはできないため、このような処理は行わないでください。
|