Oracle Tuxedo CORBA TPフレームワークでは、ユーザーが高パフォーマンスのTPアプリケーション用のサーバーを作成することを可能にするプログラミングTPフレームワークを提供します。ここでは、TPフレームワークのプログラミング・モデルおよびアプリケーション・プログラミング・インタフェース(API)について詳しく説明します。このAPIの使用方法については、『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オブジェクトと対話します。非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
コマンドが使用されます。これらのコマンドについては、オンライン・マニュアルの『Oracle 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()」を参照してください。
シングル・スレッドおよびマルチスレッドのサーバー・アプリケーションの作成方法については、『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
実装はトランザクションです。オブジェクトは、常にトランザクションで呼び出される必要があります。リクエストがトランザクションの外部で行われた場合、システムはメソッドを呼び出す前にトランザクションを自動的に開始します。メソッドの終了時にトランザクションがコミットされます。(これは、オプションのトランザクション・ポリシーを持つオブジェクトに対してAUTOTRAN
を指定した場合の動作と同じですが、この動作を達成するのに管理構成は不要であり、管理構成でオーバーライドできない点が異なります。)トランザクション・オブジェクトを含むサーバーは、XA準拠のリソース・マネージャに関連付けられているグループ内に構成する必要があります。
注意: | optional ポリシーは、管理構成によって影響を受ける唯一のトランザクション・ポリシーです。システム管理者がUBBCONFIG ファイルまたは管理ツールを使用して、AUTOTRAN 属性をインタフェースに対して設定すると、既にトランザクションに関与している場合を除いて、オブジェクトの呼出し時にトランザクションが自動的に開始されます。つまり、always ポリシーを指定した場合と同じ動作になります。 |
CosTransactions::Current::begin()
操作を使用した、アプリケーション・コードによる方法。この処理は、クライアントでもサーバーでも行うことができます。この操作の説明については、『CORBAトランザクションの使用』を参照してください。always
に設定されています。optional
に設定されており、インタフェースに対してAUTOTRAN
が設定されています。 詳細は、CORBAトランザクションの使用を参照してください。
一般に、トランザクションの結果を処理することは、開始プロセスの責任です。したがって、次のことが言えます。
Oracle Tuxedoシステムによって、以下の動作が強制的に実行されます。
CORBA::OBJ_ADAPTER
例外がクライアント・アプリケーションで発生します。この例外はトランザクションがサーバー・アプリケーションで初期化されたために発生します。したがって、クライアント・アプリケーションでは、TRANSACTION_ROLLEDBACK
のようなトランザクション・エラーを予想していません。CORBAオブジェクトは、メソッド呼出し内のトランザクションの一時停止および再開に関する規則に厳密に従う必要があります。以下に、これらの規則と規則に違反した場合のエラーについて説明します。
CORBAオブジェクト・メソッドが実行を開始すると、トランザクションに関する状態は次の3つのいずれかになります。
注意: | 操作呼出しを受信したときにトランザクションを自動的に開始する場合、各CORBAインタフェースに対して、AUTOTRAN をYes に設定します。AUTOTRAN をYes に設定しても、インタフェースがすでにトランザクション・モードにある場合は無効です。AUTOTRAN の詳細は、『CORBAトランザクションの使用』を参照してください。 |
注意: | お薦めしません。メソッドがトランザクションを再開する前に、トランザクションがタイムアウトしたり、中断されたりする可能性があります。 |
CORBA::OBJ_ADAPTER
例外をクライアントに生成し、トランザクションがロールバックされます。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
を呼び出します。トランザクションをコミットすることを支持する場合、その呼出しを行いません。ただし、コミットすることを支持してもトランザクションが実際にコミットされるとは限りません。その後、ほかのオブジェクトがトランザクションをロールバックすることを支持する可能性があるからです。
注意: | 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サーバーにはフェイルオーバーしません。
リスト3-1に示す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つのドメインのすべてのサーバーで実行できます。並行オブジェクトの利点は以下のとおりです。
並行オブジェクトの詳細は、『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の使用方法については、『CORBAサーバー・アプリケーションの作成』でも説明しています。
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;
// Default Implementations Supplied
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: Activating object - application raised TobjS::CreateServantFailed. Reason = reason. Interface =
interfaceName, OID =
oid
"
TobjS::OutOfMemory
"TPFW_CAT:22: ERROR: Activating object - application raised TobjS::OutOfMemory. Reason = reason. Interface =
interfaceName
, OID =
oid
"
CORBA::Exception
"TPFW_CAT:28: ERROR: Activating object - CORBA Exception not handled by application. Exception ID = exceptionID. Interface =
interfaceName
, OID =
oid
"
その他の例外
"TPFW_CAT:29: ERROR: Activating object - Unknown Exception not handled by application. Exception ID = exceptionID. Interface =
interfaceName
, OID =
oid
"
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: Activating object - application raised TobjS::CreateServantFailed. Reason = Application's Server::create_servant returned NULL. Interface =
interfaceName
, OID =
oid
"
ここで、interfaceName
は呼び出したインタフェースのインタフェースID、oid
は対応するオブジェクトIDです。 注意: | このリリースでは、ObjectId の長さに関する制約がなくなりました。 |
ターゲット・オブジェクト用のサーバントを作成します。このメソッドは、シングル・スレッドおよびマルチスレッド・サーバー・アプリケーションの開発をサポートします。
Tobj_Servant
create_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大きい値です。詳細は、『ファイル形式、データ記述、MIBおよびシステム・プロセス・リファレンス』の「ubbconfig(5)」
を参照してください。
Server::initialize()
で例外が発生すると、TPフレームワークがその例外を捕捉します。TPフレームワークは、initialize()
がFALSEを返した場合と同じように動作します。つまり、例外は失敗と見なされます。また、エラー・メッセージが次のように例外型ごとにユーザー・ログ(ULOG
)ファイルに書き込まれます。
TobjS::InitializeFailed
"TPFW_CAT:1: ERROR: Exception in 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ブートストラップ処理のプログラミング・リファレンス」と『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: Exception in 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ブートストラップ処理のプログラミング・リファレンス」と『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()
メソッドとクライアントが呼び出すメソッドを使用して、オブジェクトの状態を管理できます。これらのメソッドを使用してオブジェクトの状態を管理する方法は、アプリケーションのニーズによって異なります。これらのメソッドの使用方法は、「CORBAサーバー・アプリケーションの作成」を参照してください。
オブジェクトがグローバル・トランザクションに関与している場合、activate_object()
はそのグローバル・トランザクションのスコープ内で実行されます。
オブジェクトのプログラマは、格納されているオブジェクトの状態が一貫性があるかどうかをチェックする必要があります。つまり、アプリケーション・コードでは、deactivate_object()
がオブジェクトの状態を正しく保存したかどうかを示す永続性フラグを保存する必要があります。このフラグをactivate_object()
でチェックします。
activate_object()
の実行中にエラーが発生した場合、アプリケーション・コードでは、CORBA標準例外またはTobjS::ActivateObjectFailed
例外を生成する必要があります。例外が発生すると、TPフレームワークは例外を捕捉して、以下のイベントが発生します。
注意: | 操作呼出しを受信したときにトランザクションを自動的に開始する場合、各CORBAインタフェースに対して、AUTOTRAN をYes に設定します。AUTOTRAN をYes に設定しても、インタフェースがすでにトランザクション・モードにある場合は無効です。AUTOTRAN の詳細は、『CORBAトランザクションの使用』を参照してください。 |
TobjS::ActivateObjectFailed
"TPFW_CAT:24: ERROR: Activating object - application raised TobjS::ActivateObjectFailed. Reason =
reason
. Interface =
interfaceName
, OID =
oid
"
TobjS::OutOfMemory
"TPFW_CAT:22: ERROR: Activating object - application raised TobjS::OutOfMemory. Reason = reason. Interface =
interfaceName
, OID =
oid
"
CORBA::Exception
"TPFW_CAT:25: ERROR: Activating object - CORBA Exception not handled by application. Exception ID = exceptionID. Interface =
interfaceName
, OID =
oid
"
その他の例外
"TPFW_CAT:26: ERROR: Activating object - Unknown Exception not handled by application. Exception ID = exceptionID. Interface =
interfaceName, OID =
oid"
サーバントのリファレンスを追加します。このメソッドは、マルチスレッド・サーバー・アプリケーションの開発をサポートします。
注意: | 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
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 メソッドは、サーバーの停止時に、アクティブ・オブジェクト・マップに残っている各オブジェクト - TPフレームワークによって暗黙的に登録される場合(オンデマンド・アクティブ化手法TP::create_servant とサーバントのactivate_object メソッド)と、ユーザーによりTP::create_active_object_reference で明示的に登録される場合があります - に対して呼び出されます。 |
プログラマは、activate_object()
およびdeactivate_object()
メソッドとクライアントが明示的に呼び出すメソッドを使用して、オブジェクトの状態を管理できます。これらのメソッドを使用してオブジェクトの状態を管理する方法は、アプリケーションのニーズによって異なります。これらのメソッドの使用方法は、「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: De-activating object - application raised TobjS::DeactivateObjectFailed. Reason =
reason
. Interface =
interfaceName, OID =
oid"
CORBA::Exception
"TPFW_CAT:28: ERROR: De-activating object - CORBA Exception not handled by application. Exception ID =
exceptionID
. Interface =
interfaceName
, OID =
oid
"
その他の例外
"TPFW_CAT:29: ERROR: De-activating object - Unknown Exception not handled by application. Exception ID =
exceptionID
. Interface =
interfaceName
, OID =
oid
"
オブジェクトが同時のリエントラント呼出しをサポートすることを示します。このメソッドは、マルチスレッド・サーバー・アプリケーションの開発をサポートします。
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ブートストラップ処理のプログラミング・リファレンス」と『CORBAトランザクションの使用』を参照してください。 |
このメソッドは、グローバル・トランザクションに関与する各サーバーに対してServer::release()
メソッドから1回呼び出す必要があります。これには、XAリソース・マネージャにリンクされているサーバーと、グローバル・トランザクションに関与し、XA準拠リソース・マネージャに実際にはリンクされていないサーバーが含まれます。
close_xa_rm()
メソッドは、リソース・マネージャに固有のクローズ呼出しのかわりに呼び出します。リソース・マネージャの初期化セマンティクスはそれぞれ異なるので、特定のリソース・マネージャを閉じるための情報を、Oracle TuxedoシステムのUBBCONFIG
ファイルのGROUPS
セクションにあるCLOSEINFO
パラメータに指定します。
CLOSEINFO
文字列の形式は、基礎となるリソース・マネージャを提供しているデータベース・ベンダーの要件によって異なります。CLOSEINFO
パラメータの詳細は、Oracle Tuxedoアプリケーションの設定と、『ファイル形式、データ記述、MIBおよびシステム・プロセス・リファレンス』の「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
ですでに使用されているため、オブジェクトを明示的にアクティブ化できませんでした。サーバントは、単一のObjectId
でのみ使用できます。別のObjectId
を含むオブジェクトを事前にアクティブ化するには、アプリケーションが複数のサーバントを作成し、ObjectId
ごとに1つずつ事前にアクティブ化する必要があります。
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
アクティブ化ポリシーを指定すると、次の問題が発生する可能性があります。
ActivateObjectFailed
例外をスローするようにインタフェースのactivate_object
メソッドを記述します。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(ゼロ)を渡します。Oracle Tuxedoシステムの管理者は、UBBCONFIG
ファイルでルーティング規則を指定して、ファクトリ・ベース・ルーティングを構成します。この機能の詳細は、オンライン・ドキュメントのOracle Tuxedoアプリケーションの設定を参照してください。
create_object_reference()
メソッドの例外は以下のとおりです。
InvalidInterface
InvalidObjectId
create_object_reference()
メソッドの呼出しは、サーバー・アプリケーションの役割です。このメソッドによって、オブジェクト参照が作成されます。作成されたオブジェクト参照は、オブジェクトへのアクセスで使用するクライアントに渡されます。
通常、サーバー・アプリケーションではこのメソッドを以下の2か所で呼び出します。
create_object_reference()
メソッドの呼出し方法とタイミングの例については、『CORBAサーバー・アプリケーションの作成』を参照してください。
Object
次のサンプル・コードは、criteria引数の使用方法を示しています。
CORBA::NVList_ptr criteria;
CORBA::Long branch_id = 7;
CORBA::Long account_id = 10001;
CORBA::Any any_val;
// Create the list and assign to _var to cleanup on exit
CORBA::ORB::create_list (2, criteria);
CORBA::NVList_var criteria_var(criteria);
// Add the BRANCH_ID
any_val <<= branch_id;
criteria->add_value("BRANCH_ID", any_val, 0);
// Add the ACCOUNT_ID
any_val <<= account_id;
criteria->add_value("ACCOUNT_ID", any_val, 0);
// Create the object reference.
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
と関連付けられたサーバントを指定することで、オブジェクトの非アクティブ化をリクエストします。 オブジェクトが実行中の場合、TPでは非アクティブ化対象としてオブジェクトをマークして、current-object形式と同じように、オブジェクトのメソッドが終了するまで待機してから非アクティブ化します。オブジェクトが実行中でない場合、TPフレームワークでは直ちにオブジェクトを非アクティブ化できます。非アクティブ化のステータスは、呼出し側に通知されません。オブジェクトが非アクティブ化されると、TPフレームワークではまずアクティブ・オブジェクト・マップからオブジェクトが削除されます。次に、理由コード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ブートストラップ処理のプログラミング・リファレンス」と『CORBAトランザクションの使用』を参照してください。 |
グローバル・トランザクションに関与するサーバーごとにServer::initialize()
メソッドから1回、このメソッドを呼び出す必要があります。グローバル・トランザクションに関与しているすべてのサーバーだけでなく、XAリソース・マネージャにリンクされたサーバーも含まれますが、XA準拠のリソース・マネージャに実際にはリンクされていません。
open_xa_rm()
メソッドは、リソース・マネージャに固有のオープン呼出しのかわりに呼び出します。リソース・マネージャの初期化セマンティクスはそれぞれ異なるので、特定のリソース・マネージャを開くための情報を、UBBCONFIG
ファイルのGROUPS
セクションにあるOPENINFO
パラメータに指定します。
OPENINFO
文字列の形式は、基礎となるリソース・マネージャを提供しているデータベース・ベンダーの要件によって異なります。CLOSEINFO
パラメータの詳細は、Oracle Tuxedoアプリケーションの設定と、『ファイル形式、データ記述、MIBおよびシステム・プロセス・リファレンス』の「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() 呼出しの前に、現在のトランザクションを一時停止しなければならない場合があります。トランザクションの一時停止と再開方法については、オンライン・マニュアルの『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() 呼出しの前に、現在のトランザクションを一時停止しなければならない場合があります。トランザクションの一時停止と再開方法については、オンライン・マニュアルの『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オブジェクトに対する呼出しがプロセスで発生するようにプログラミングすることはできないため、このような処理は行わないでください。