Oracle Tuxedoのアプリケーション・トランザクション・モニター・インタフェース(ATMI)を開発する場合、まず設計に関連する各種の概念や利用できるツールを確認しておきます。たとえば、クライアント (外部からの入力データが収集されて処理される方法)、およびサーバー (入力データを処理するビジネス・ロジックが定義されたプログラム)について理解しておきます。また、型付きバッファ (クライアント・プログラムがメモリー領域を割り当て、別のプログラムにデータを送る方法)についても理解しておきます。Oracle Tuxedoのメッセージング・パラダイムも重要な概念です。ATMIクライアント・プログラムは、ATMIライブラリを呼び出すことによって、Oracle Tuxedoシステムにアクセスします。ATMIライブラリのほとんどの呼出しでは、リクエスト/レスポンス型や会話型などの通信方法がサポートされています。これらの通信は、Oracle Tuxedoアプリケーションの基本部分です。
アプリケーション・キュー、イベント・ベースの通信、ATMIの使用方法の概念、および利用できるツールの詳細は、『Oracle Tuxedo ATMIの紹介』の「Oracle Tuxedo ATMI環境の基本アーキテクチャ」を参照してください。アプリケーションのプログラミングの詳細は、『C言語を使用したOracle Tuxedo ATMIアプリケーションのプログラミング』および『COBOLを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』を参照してください。
Oracle Tuxedoのクライアントは、CまたはC++などのプログラミング言語でプログラムを作成するのと同じように作成できます。Oracle Tuxedoシステムには、Oracle Tuxedo ATMIと呼ばれるC言語に基づいたプログラミング・インタフェースが用意されています。ATMIは、Oracle Tuxedoのクライアントとサーバーの開発をサポートする使いやすいインタフェースです。
注: | Oracle Tuxedo ATMIでは、COBOLインタフェースもサポートされています。図1-1は、C/C++ APIの例です。 |
tpchkauth()
を呼び出して、アプリケーションに参加するために必要なセキュリティ・レベルを決定します。戻り値として返されるセキュリティ・レベルには、セキュリティなし、アプリケーション・パスワード、アプリケーション認証、アクセス制御リスト、リンク・レベル暗号化、公開鍵の暗号化、監査などがあります。これらの値は、セキュリティ・レベルを設定している場合にのみ返されます。tpinit()
を呼び出して、Oracle Tuxedoアプリケーションに接続します。必要なセキュリティ情報は、tpinit()
の引数としてアプリケーションに渡されます。tpterm()
を呼び出して、Oracle Tuxedoアプリケーションとの接続を解除します。
Oracle Tuxedoのクライアントとサーバーは、ATMIプログラミング・インタフェースを使用して作成できます。ただし、Oracle Tuxedoサーバーは完全なプログラム、つまり標準的なmain
関数を使ったプログラムとして開発されたものではありません。かわりに、アプリケーション開発者は、サービスと呼ばれる特定のビジネス関数を使用します。この関数は、Oracle Tuxedoのバイナリ形式でコンパイルされて、実行可能サーバーが生成されます。
Oracle Tuxedoサーバーが起動すると、停止メッセージを受信するまで稼働し続けます。通常、Oracle Tuxedoサーバーは停止して再起動するまでに、何千ものサービス呼出しを行います。
tpsvrinit()
関数を呼び出します。プログラマは、この関数を使用して、後で使用するアプリケーション・リソース(データベースなど)を開きます。tpsvrdone()
関数を呼び出します。プログラマは、この関数を使用して、tpsvrinit()
によって開かれたアプリケーション・リソースを閉じます。tpreturn()
関数を呼び出してサービス・リクエストを終了させ、必要に応じて呼出し側のクライアントにバッファを返します。
Oracle Tuxedoシステムでは、すべての通信が型付きバッファを使用して行われます。Oracle Tuxedoシステムには通信を行うための各種のバッファ型があり、アプリケーション開発者がその型を選択することができます。Oracle Tuxedoシステムで渡されるすべてのバッファには特殊なヘッダーがあり、Oracle Tuxedo ATMI (tpalloc()
、tprealloc()
、およびtpfree()
)を介してバッファの割当てや解放が行われます。
型付きバッファ機能によって同じバッファ型を共有できるようになり、どの種類のネットワークやプロトコルでも、Oracle Tuxedoシステムでサポートされるどの種類のCPUアーキテクチャやオペレーティング・システムにも、データを送ることができるようになります。分散型の環境で型付きバッファを使用すると、各種の通信ネットワークを介してリンクされた異種コンピュータ間でデータを転送する場合に、クライアントおよびサーバーでデータを準備するための処理が簡略化されます。そのため、プログラマはこのような機能をプログラムに組み込む必要がなくなり、本来のビジネス・ロジックの開発に集中することができます。
Oracle Tuxedo ATMIには、アプリケーションで使用できる次のような通信モデルがあります。
同期呼出しを行う場合、Oracle Tuxedo ATMIクライアントはATMI関数tpcall()
を使用して、Oracle Tuxedo ATMIサーバーにリクエストを送ります。この関数は、Oracle Tuxedoサーバーを名前で呼び出すのではなく、指定されたサービスを呼び出します。指定されたサービスは、そのサービスを提供できる任意のサーバーによって提供されます。クライアントは、送信したサービス・リクエストが処理されるまで待機します。このリクエストに対する応答を受け取るまで、クライアントはほかの操作を行うことができません。つまり、クライアントでは、応答を受信するまで操作が「ブロック」されます。
非同期呼出しを行う場合、クライアントは2つのATMI関数を呼び出します。つまり、tpacall(3c)関数を使ってサービスをリクエストし、tpgetrply(3c)関数を使って応答を取り出します。この方法は、クライアントがリクエストを送り、その応答を受け取るまでに別の操作を行う場合に使用します。
サービスは、Oracle Tuxedo ATMIクライアントとして動作して、別のOracle Tuxedoサービスを呼び出すことができます。つまり、サービスをリクエストして、そのサービスが別のサービスをリクエストすることができます。たとえば、Oracle TuxedoクライアントがサービスXを呼び出し、その応答を待ちます。その後、サービスXはサービスYを呼び出し、その応答を待ちます。サービスXが応答を受け取ると、サービスXは呼出し側のクライアントにその応答を返します。この方法では、サービスXがサービスYからの応答を取得し、その応答になんらかの処理を行い、返されたバッファを変更してから最終的な応答をクライアントに返すことができます。
呼出しを転送すると、ネストされたサービスが、最初に呼び出されたサービスを経由せずに直接ATMIクライアントに応答を返すことができます。このため、最初のサービスはほかのリクエストを処理できるようになります。この機能は、最初に呼び出されたサービスが配信エージェントとしてのみ機能し、ネストされたサービスから返された応答にデータを追加しない場合に使用します。
呼出しを転送する場合、クライアントによって呼び出されたサービスはtpforward(3c)関数を使用して、別のサービスYにリクエストを渡します。このような処理でのみ、Oracle Tuxedoサービスはtpreturn(3c)を呼び出さずに、サービス呼出しを終了することができます。
呼出しの転送は、クライアントに透過的に行われます。つまり、同じクライアント・コードを使用して、1つのサービスによって処理されるサービス・リクエストも、複数のサービスによって処理されるサービス・リクエストも扱うことができます。
Oracle Tuxedo ATMIクライアントとサービス間で、ステートフルで複数のバッファを送信する必要がある場合は、Oracle Tuxedoの会話型通信を使用します。
サーバーが一度会話に参加すると、会話が終了するまでそのサーバーを利用できなくなるため、Oracle Tuxedo会話型通信は慎重に使用します。会話型通信を実装するには、次の手順をコードに記述します。
非請求通知を有効にするには、Oracle Tuxedo ATMIクライアントでtpsetunsol()
関数を使用して非請求メッセージ・ハンドルを作成します。非請求メッセージを送信する場合、Oracle Tuxedoクライアントまたはサーバーは、単一のクライアントにメッセージを送信するときはtpnotify()
関数、複数のクライアントに同時にメッセージを送信するときはtpbroadcast()
関数を使用します。クライアントがメッセージを受信すると、Oracle Tuxedoシステムはクライアントの非請求ハンドラ関数を呼び出します。
シグナル・ベースのシステムでは、クライアントは非請求メッセージをポーリングする必要はありません。ただし、非シグナル・ベースのシステムでは、クライアントはtpchkunsol()
関数を使用して、非請求メッセージを確認する必要があります。クライアントがサービス・リクエストを作成すると、暗黙的にtpchkunsol()
が呼び出されます。
注: | tpack フラグ・ビットを設定してtpnotify() を呼び出すと、リクエストに対する肯定応答が送信されます。 |
イベント・ベースの通信では、イベントをアプリケーション・キュー、ログ・ファイル、およびシステム・コマンドにポストできます。Oracle Tuxedo ATMIクライアントは、tpsubscribe()
関数を使用してユーザー定義のイベントをサブスクライブし、Oracle Tuxedoサービスまたはクライアントがtppost()
関数を呼び出したときに非請求メッセージを受信することができます。また、ATMIクライアントは、Oracle Tuxedoシステムがイベントを検出したときにトリガーされるシステム定義のイベントをサブスクライブすることもできます。たとえば、サーバーが異常終了すると、.SysServerDied
イベントがポストされます。このイベントのポストはOracle Tuxedoシステムによって行われるため、アプリケーション・サーバーがポストする必要がありません。
/Qシステムとのインタフェースとして、Oracle Tuxedoクライアントは2つのATMI関数を使用します。つまり、キュー・スペースにメッセージを格納するtpenqueue()
関数と、キュー・スペースからメッセージを取得するtpdequeue()
関数を使用します。
次の図は、ピア・ツー・ピアの非同期メッセージングを表しています。この例では、クライアントはtpenqueue()
を使用してサービスにメッセージを登録します。オプションで、tpenqueue()
の呼出しに、応答キューおよび異常終了キューの名前を指定できます。クライアントは、メッセージに付ける相関識別子の値を指定することもできます。この値は、キュー間で同じです。そのため、キューのメッセージに対応付けられたどの応答メッセージまたは異常終了メッセージも、応答キューまたは異常終了キューから読み取られるときに識別できます。
クライアントは、デフォルトのキューの順序付けを使用するか(たとえば、メッセージがキューから出されるまでの時間)、またはデフォルトのキューの順序付けの無効化を指定すること(たとえば、メッセージをキューの先頭に置くこと、またはキューの別のメッセージの前に置くこと)ができます。tpenqueue()
は、TMQUEUE
サーバーにメッセージを送信し、そのメッセージは安定ストレージのキューに登録され、肯定応答がクライアントに送信されます。肯定応答は、クライアントが直接確認することはできません。ただし、クライアントが正常な戻り値を取得すると、肯定応答が送られたと見なすことができます。異常終了の戻り値には、異常終了の内容についての情報が含まれています。キュー・マネージャによって割り当てられたメッセージ識別子は、アプリケーションに返されます。この識別子は、特定のメッセージをキューから取り出す場合に使用します。 また、この識別子は、別のtpenqueue()
内で使用して、キューに次に登録されるメッセージの前にあるメッセージを識別することができます。
キューに登録されたメッセージをキューから取り出すには、そのメッセージをキューに登録しているトランザクションが正常にコミットされる必要があります。クライアントはtpdequeue()
を使用して、キューからメッセージを取り出します。
クライアントはサーバー上のサービスXへのメッセージをキューに登録します。サービスは、メッセージがアクティブになった場合、およびメッセージの処理条件が満たされた場合に、メッセージを受信します。たとえば、メッセージが金曜日の午後6時にアクティブになるようにエンコードされている場合などに、メッセージを受け取ります。サービスが完了すると、キュー・スペースに応答が返されます。クライアントは、そこから応答を取得します。
この方法は、サービスに透過的です。つまり、同じアプリケーション・コードを使用して、キューを経由してサービスを呼び出すことも、tp(a)call
関数を使って直接サービスを呼び出すこともできます。
トランザクションを実装する場合、アプリケーション・プログラマは次の3つのATMI関数を使用します。
トランザクションに含まれるコードは、開始、コミット、および停止のみです。
次の例では、クライアントがトランザクションを開始し、2つのサービスをリクエストし、トランザクションをコミットしています。サービス・リクエストはトランザクションが開始されてからコミットされるまでの間に作成されるため、どちらのサービスも同じトランザクションに参加します。