![]() |
![]() |
|
|
メッセージのキューからの取り出し
次は、tpdequeue() の構文です。
#include <atmi.h>
int tpdequeue(char *qspace, char *qname, TPQCTL *ctl, \
char **data, long *len, long flags)
この呼び出しが行われると、qspace で識別されるキュー・スペース内の qname キューからメッセージを取り出すようにシステムが指示されます。メッセージは、*data が指すアドレスにあるバッファ (tpalloc(3c) によって割り当てられたもの) に挿入されます。len はデータの長さを示します。tpdequeue() から返された len が 0 の場合、そのメッセージにはデータ部分がないことを示します。flags にビット設定を行うと、システムに tpenqueue() 呼び出しの処理方法が通知されます。ctl が指す TPQCTL 構造体には、この呼び出しの処理方法についての詳細な情報が記述されます。
tpdequeue(3c) の引数
tpdequeue(3c) の処理を制御するいくつかの重要な引数があります。その一部について、以下に説明します。
tpdequeue(): qspace 引数
qspace は、管理者によって既に作成されたキュー・スペースを識別します。TMQUEUE サーバがコンフィギュレーション・ファイルの SERVERS セクションで定義されている場合、そのサーバが提供するサービス名は、実際のキュー・スペース名 (GROUPS セクションの OPENINFO パラメータの一部として指定されます) のエイリアスになります。たとえば、アプリケーションがサーバ TMQUEUE を使用する場合、qspace 引数が指す値は、TMQUEUE が宣言するサービス名になります。サービス名のエイリアスが何も定義されていない場合、デフォルトのサービス名はサーバ名 TMQUEUE と同じになります。その場合、コンフィギュレーション・ファイルには次が記述されています。
TMQUEUE
SRVGRP = QUE1 SRVID = 1
GRACE = 0 RESTART = Y CONV = N
CLOPT="-A"
または
CLOPT = "-s TMQUEUE"
サーバ・グループ QUE1 のエントリには、OPENINFO パラメータを使用して、リソース・マネージャ、デバイスのパス名、およびキュー・スペース名を指定します。クライアント・プログラムにおける qspace 引数は、次のように記述されます。
if (tpdequeue("TMQUEUE", "REPLYQ", (TPQCTL *)&qctl,
(char **)&reqstr, &len,TPNOTIME) == -1) {
エラー・チェック
}
TMQUEUE(5) リファレンス・ページの例では、サーバを作成してコンフィギュレーション・ファイルで指定する際に、サービスのエイリアスを指定する方法が示されています。「サンプル・アプリケーション」 のサンプル・プログラムでも、サービスまたはキュー・スペース名のエイリアスが指定されています。
tpdequeue(): qname 引数
キュー・スペース内のキュー名は、そのキュー・スペースにアクセスするアプリケーション間で一貫していなければなりません。これは、応答キューでは特に重要です。qname が応答キューを参照する場合、管理者はほかのキューと同じ方法で応答キュー、そして多くの場合、エラー・キューも作成します。qname は、メッセージまたは応答を取り出すキューを指すポインタです。
tpdequeue(): data および len 引数
この 2 つの引数は、tpenqueue() で使用される場合と若干意味が異なります。*data は、キューから取り出されたメッセージをシステムが格納するバッファのアドレスを指します。tpdequeue() が呼び出された場合に、この値が NULL であることはエラーです。
tpdequeue() が戻ると、len は取り出されたデータのデータ長情報を持つ long 型を指します。0 は応答にデータがなかったことを示します。アプリケーションによっては、これは正当で正常な応答です。長さ 0 の応答を受信した場合でも、それをキューに登録された要求の正常処理を示すために使用できます。バッファが tpdequeue() 呼び出しの前と比べて変更されているかどうかを確認する場合は、tpdequeue() 呼び出しの前にデータ長を保存し、それを呼び出しが終了した後で len と比較します。
tpdequeue(): flags 引数
flags の値は、tpdequeue() 呼び出しの処理方法を BEA Tuxedo システムに通知するために使用されます。次は、有効なフラグです。
TPQCTL 構造体
tpdequeue() の 3 番目の引数は、TPQCTL 型の構造体へのポインタです。TPQCTL 構造体には、アプリケーションで使用されるメンバと BEA Tuxedo システムで使用されるメンバがあり、アプリケーション・プログラムとキュー機能間の両方向でパラメータがやり取りされます。tpdequeue() を呼び出すクライアントはフラグを設定して、システムで値が提供されるべきフィールドをマークします。前述のように、この構造体は tpenqueue() でも使用されます。一部のメンバは、tpenqueue() だけに適用されます。この構造体全体のコード例は、「tpqctl_t 構造体」 に示されています。
tpdequeue() への入力では、次のフィールドを TPQCTL 構造体に設定します。
long flags; /* どの値が設定されるかを示します。 */
char msgid[32]; /* キューから取り出すメッセージの ID */
char corrid[32]; /* キューから取り出すメッセージの相関識別子 */
次は、tpdequeue() の入力として有効なフラグです。
次は、tpdequeue() からの出力情報を制御する flags パラメータの有効なビットです。どのフラグ・ビットでも、tpdequeue() の呼び出し時にオンになっていると、メッセージがキューに登録されたときに提供された値が、構造体の対応するフィールド (「tpqctl_t 構造体」 を参照) に格納され、そのビットは設定されたままになります。値が使用できない (つまり、メッセージがキューに登録されたときに値が指定されなかった)場合、または tpdequeue() を呼び出したときにビットが設定されなかった場合、tpdequeue() はフラグがオフの状態で完了します。
flags パラメータの残りのビットは、tpdequeue() が呼び出されるとクリア (0 に設定) されます。これには、TPQTOP、TPQBEFOREMSGID、TPQTIME_ABS、TPQTIME_REL、TPQEXPTIME_ABS、TPQEXPTIME_REL、および TPQEXPTIME_NONE が含まれます。これらのビットは、tpenqueue() の入力情報を制御する flags パラメータの有効なビットです。
tpdequeue() の呼び出しが失敗し、tperrno(5) に TPEDIAGNOSTIC が設定された場合は、失敗の原因を示す値が ctl->diagnostic に返されます。ctl->diagnostic の有効なコードには、「TPQCTL 構造体」 に示されている tpdequeue() の値 (QMENOSPACE と QMERELEASE を除く) のほかに、次のものがあります。
TPQWAIT の使用
TPQCTL 構造体の flags に TPQWAIT が設定されて tpdequeue() が呼び出された場合に、メッセージをすぐに取り出すことができないと、tpdequeue() が呼び出し元に制御を返す前に、TMQUEUE サーバ は tpdequeue() 要求に一致するメッセージがキューに到着するのを待ちます。TMQUEUE プロセスは待機中の要求を無視し、ほかのプロセスの要求を処理しながら、最初の要求の条件が満たされるのを待ちます。TPQGETBYMSGID や TPQGETBYCORRID も指定されている場合、サーバは指定されたメッセージ識別子や相関識別子を持つメッセージをキューから取り出せるようになるまで待ちます。このどちらのフラグも設定されていない場合、サーバは任意のメッセージがキューに登録されるまで待ちます。呼び出しがトランザクション・モードの場合、サーバの待機時間は、呼び出し元のトランザクション・タイムアウトによって制御されます。呼び出しがトランザクション・モードでない場合、TMQUEUE サーバの CLOPT パラメータに指定される -t オプションで制御されます。
TMQUEUE サーバは、要求を処理するアクション・リソースを利用できる限り、複数の待機中 TPDEQUEUE() 要求を同時に処理できます。十分なアクション・リソースがキュー・スペースに対して設定されていない場合、TPDEQUEUE() は失敗します。使用しているシステムがこれに該当する場合は、キュー・スペースに対するアクション・リソースの数を増やしてください。
TMQFORWARD サービス使用時のエラー処理
キューからのメッセージの取り出しで、エラー処理の最良の方法を考慮する場合、次の 2 種類のエラーを区別しておきます。
デフォルトでは、メッセージがトランザクション内でキューから取り出され、そのトランザクションがロールバックされると、retry パラメータが 0 より大きい場合は、そのメッセージはキューに戻されて、再度キューからの取り出しと実行が可能になります。一時的な障害が解消されるように (たとえば、データベースのロックを別のトランザクションが解除するように) 少し時間をおいてから、メッセージの取り出しと実行を再度試みます。通常、再試行の回数に上限を設定することも、アプリケーション不備によってリソースを著しく浪費することを防ぐために有用です。管理者がキューを設定するときに、再試行の回数と遅延時間 (秒単位) の両方を指定できます。再試行の回数 0 は、再試行が行われないことを示します。再試行の回数が上限に達すると、管理者がキュー・スペースに設定するエラー・キューにメッセージが移動されます。エラー・キューが設定されていない場合、再試行回数の上限に達したメッセージは単に削除されます。エラー・キューにあるメッセージは、管理者によって処理されなければなりません。管理者は、アプリケーションの要件を満たす方法で発信元に通知する必要があります。選択されたメッセージ処理方法は、メッセージをキューに登録した発信元プログラムにほとんど透過的です。メッセージは一度正常にキューに登録されると、tpenqueue() のパラメータおよびキューの属性に従って処理されることが実質的には保証されます。メッセージがエラー・キューに移動されたことの通知は、キューのパラメータを適切に調整されたシステムではほとんどありません。
異常終了キュー (通常、キュー・スペースのエラー・キューとは異なります) は、キューに登録された各メッセージと対応付けられます。このキューは、異常終了メッセージを置く場所として、キューにメッセージを登録する呼び出しで指定されます。特定の要求に対する異常終了メッセージは、アプリケーション生成の相関識別子で識別できます。相関識別子は、キューにメッセージを登録するときに、そのメッセージと対応付けられます。
成功するまで (または事前に定義された回数まで) 再試行を繰り返すというデフォルトの動作は、時間が経過すれば解決されるような一時的な障害が失敗の原因であり、メッセージが後から適切に処理される場合は適しています。
障害が一時的なものではない場合もあります。たとえば、存在しないアカウントでの操作を要求するメッセージがキューに入れられている場合 (アプリケーションも適当な時間に存在していない場合) です。その場合、再試行してリソースを浪費しないようにします。アプリケーション・プログラマまたは管理者が、特定の操作の失敗が一時的ではないと判断した場合、単に再試行回数を 0 に設定します。ただし、この場合、このようなメッセージが入るキュー・スペースのエラー・キューを継続的にクリアするメカニズム (キューを定期的に読み取るバックグラウンドのクライアントなど) が必要です。また、同じサービスに対する障害でも、一時的なもの (データベース・ロックの競合など) であったり、永続的なもの (アカウントが存在しないなど) であったりする場合が多くあります。
メッセージが TMQFORWARD によって処理される (キューから取り出され、tpcall() を介してアプリケーションに渡される) 場合、tpcall() が返す情報には、TPESVCFAIL エラーが一時的な障害と永続的な障害のどちらによって生じたものであるかを示すメカニズムはありません。
キューからの取り出しをアプリケーションが処理する場合、簡単な解決方法はたとえ操作が失敗しても、そのサービスに対して成功を返すことです。つまり、TPSUCCESS を設定して tpreturn を実行します。これにより、トランザクションはコミット可能になり、メッセージはキューから削除されます。応答メッセージが使用されている場合、サービスから返されるバッファの情報によって操作の失敗を示すことができ、メッセージが応答キューに登録されます。tpreturn の rcode 引数も、アプリケーション固有の情報を返すために使用できます。
サービスが失敗し、トランザクションをロールバックする必要がある場合、TMQFORWARD が処理をそれ以上行わずに、2 番目のトランザクションを実行してキューからメッセージを削除するかどうかは明確ではありません。デフォルトでは、TMQFORWARD は失敗したサービスに対するメッセージを削除しません。TMQFORWARD のトランザクションはロールバックされ、メッセージはキューに格納されます。TMQFORWARD にコマンド行オプションを指定すると、サービスが失敗して 0 より長い応答メッセージが返された場合に、メッセージがキューから削除されます。メッセージは、2 番目のトランザクションで削除されます。この処理を行うには、キューに遅延時間および再試行回数を設定する必要があります。メッセージが異常終了キューに対応付けられている場合、メッセージがキューから削除されたトランザクションと同じトランザクションで、応答データが異常終了キューに登録されます。
TMQFORWARD を通して呼び出されたサービスからの応答をキューから取り出す手順
アプリケーションがキューに登録されたメッセージに対する応答を要求している場合、次の手順に従います。
TPQCORRID TPQREPLYQ
TPQFAILUREQ TPQMSGID
この呼び出しを行う前に、corrid、replyqueue、および failurequeue の値を設定します。呼び出しから制御が戻ったら、corrid を保存します。
TPQCORRID TPQREPLYQ
TPQFAILUREQ TPQMSGID
TPQGETCORRID
この呼び出しを行う前に、保存した相関識別子を使用して corrid に入力します。tpdequeue() の呼び出しが失敗し、tperrno(5) に TPEDIAGNOSTIC が設定された場合、詳しい情報を diagnostic から取得できます。エラー・コード QMENOMSG を受信した場合、キューから取り出すことのできるメッセージがなかったことを示します。
TPQCORRID TPQREPLYQ
TPQFAILUREQ TPQMSGID
TPQGETBYCORRID
corrid に相関識別子を挿入します。呼び出しから制御が戻ったら、len を調べてデータが受信されたかどうかを確認し、また、urcode を調べてサービスがユーザ戻りコードを返したかどうかを確認します。
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|