目次 前 次 PDF


Oracle Tuxedo /QのC言語プログラミング

Oracle Tuxedo /QのC言語プログラミング
このトピックには次の項が含まれます:
はじめに
ここでは、キューへのメッセージの登録とキューからのメッセージの取出しを行うATMI C言語関数tpenqueue(3c)tpdequeue(3c)、およびいくつかの補助関数の使用方法について説明します。
前提知識
キュー式メッセージ機能機能を使用するクライアント・プログラムまたはサーバー・プログラムをコーディングするOracle TUXEDOプログラマには、Oracle Tuxedo ATMIにバインドされたC言語についての知識が必要です。Oracle Tuxedoプログラミングに関する全般的な説明については、『C言語を使用したOracle Tuxedo ATMIアプリケーションのプログラミング』を参照してください。ATMI関数の詳細は、『Oracle Tuxedo ATMI C言語関数リファレンス』を参照してください。
リクエストの発信元
Oracle Tuxedo /Qのキューにメッセージを登録する呼出しは、アプリケーションに関連付けられているあらゆるクライアント・プロセスまたはサーバー・プロセスから行うことができます。たとえば、次の発信元があります。
キュー・スペースと同じマシン、またはネットワーク上の別のマシンにあるクライアントまたはサーバー。
会話型プログラム。ただし、キュー(または、TMQUEUE(5)サーバー)との会話接続は確立できません。
サーバー側の代理プロセスを介するワークステーション・クライアント。管理インタフェースも完全にサーバー側にあります。
デフォルトの場合の注意事項
ここでは、Oracle Tuxedo /Qプログラミングについて、1-2ページの図「キュー・サービスの呼出し」の主に左側部分について説明します。この図では、クライアント(または、クライアントとして機能するプロセス)はtpenqueue(3c)を呼び出し、TMQUEUE(5)サーバーを通して使用できるキュー・スペースを指定して、メッセージをキューに登録しています。クライアントは、その後、TMQUEUEへのtpdequeue(3c)呼出しを介して、応答を取得します。
1-2ページの図「キュー・サービスの呼出し」では、キューに入れられたメッセージが、サーバーTMQFORWARD(5)によってキューから取り出され、処理のためにtpcall(3c)を介してアプリケーション・サーバーに送信されています。tpcall()に対する応答が受信されると、TMQFORWARDは応答メッセージをキューに登録します。TMQFORWARDの主な目的は、キュー・スペースと既存のアプリケーション・サービスとの間にインタフェースを提供することです。そのため、アプリケーションにコードを追加する必要はありません。そのため、ここでは、クライアントとキュー・スペースとの間の処理を中心に説明します。
キュー式メッセージ機能の使用方法を簡単に示すサンプルがソフトウェアに提供されています。詳細は、A-1ページの「サンプル・アプリケーション」を参照してください。
メッセージのキューへの登録
次は、tpenqueue()の構文です。
#include <atmi.h>
int tpenqueue(char *qspace, char *qname, TPQCTL *ctl,
char *data, long len, long flags)
tpenqueue()が呼び出されると、qspaceで識別されるキュー・スペース内のqnameキューにメッセージを格納するようにシステムが指示されます。メッセージはdataが指すバッファ内にあり、その長さはlenで示されます。flagsにビット設定を行うと、システムにtpenqueue()呼出しの処理方法が通知されます。登録されたメッセージおよび応答の処理方法のさらに詳しい情報は、ctlが指すTMQCTL構造体で定義されます。
tpenqueue(3c)の引数
tpenqueue(3c)の処理を制御するいくつかの重要な引数があります。その一部について、以下に説明します。
tpenqueue(): qspace引数
qspaceは、管理者によってすでに作成されたキュー・スペースを識別します。サーバーが構成ファイルの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 (tpenqueue("TMQUEUE", "STRING", (TPQCTL *)&qctl,
(char *)reqstr, 0,0) == -1) {
Error checking
}
「TMQUEUE(5)」リファレンス・ページの例では、サーバーを作成して構成ファイルで指定する際に、サービスの別名を指定する方法が示されています。A-1ページの「サンプル・アプリケーション」のサンプル・プログラムでも、サービスの別名が指定されています。
tpenqueue(): qname引数
キュー・スペース内で、キューを使用してサービスを呼び出している場合、メッセージ・キューはリクエストを処理できるアプリケーション・サービスに従って命名されます。qnameは、そのようなアプリケーション・サービスを指すポインタです。それ以外の場合、qnameは、アプリケーション(メッセージをキューに登録したアプリケーション、または別のアプリケーション)によってキューから取り出されるまで、メッセージを格納しておく場所を単に示す名前です。
tpenqueue(): dataおよびlen引数
dataは、処理対象のメッセージが格納されたバッファを指すポインタです。そのバッファは、tpalloc(3c)を呼び出して割り当てられたものであることが必要です。lenは、メッセージの長さを指定します。Oracle Tuxedoのバッファ・タイプには、メッセージの長さを指定する必要がないもの(FMLなど)もあります。その場合、lenは無視されます。dataはNULLにすることもできます。その場合、lenは無視され、メッセージはデータ部分なしでキューに登録されます。
tpenqueue(): flags引数
flagsの値は、tpenqueue()呼出しの処理方法をOracle Tuxedoシステムに通知するために使用されます。次は、有効なフラグです。
TPNOTRAN
呼出し側がトランザクション・モードにあり、このフラグが設定されていると、メッセージは呼出し側と同じトランザクション内ではキューに登録されません。このフラグを設定するトランザクション・モードの呼出し側は、メッセージをキューに登録するときに、やはりトランザクション・タイムアウトの影響を受けます(それ以外はなし)。キューへのメッセージの登録が失敗した場合、呼出し側のトランザクションは影響されません。
TPNOBLOCK
ブロッキング状態が存在する場合、メッセージはキューに登録されません。このフラグが設定されている場合に、メッセージの転送先である内部バッファがいっぱいであるなどのブロッキング状態が存在すると、呼出しは失敗し、tperrno(5)TPEBLOCKが設定されます。このフラグが設定されていて、ターゲットのキューが別のアプリケーションによって排他的にオープンされているなどのブロッキング条件が存在する場合には、呼出しは失敗してtperrno()TPEDIAGNOSTICが設定され、TPQCTL構造体の診断フィールドはQMESHAREに設定されます。後者の場合、Oracle Tuxedoシステム以外のOracle製品に基づくほかのアプリケーションが、キューイング・サービスAPI (QSAPI)を使用して読取りと書き込み、またはそのいずれかを排他的に行うためにキューをオープンしています。
TPNOBLOCKが設定されていない場合に、ブロッキング状態が存在すると、その状態が解消されるかタイムアウト(トランザクション・タイムアウトまたはブロッキング・タイムアウト)が発生するまで、呼出し側はブロックされます。タイムアウトが発生した場合、呼出しは失敗し、tperrno()TPETIMEが設定されます。
TPNOTIME
このフラグを設定すると、呼出し側は無制限にブロックでき、ブロッキング・タイムアウトが適用されなくなります。ただし、トランザクション・タイムアウトは発生する可能性があります。
TPSIGRSTRT
このフラグが設定されていると、基底のシステム・コールがシグナルによって中断された場合、中断されたシステム・コールが再度呼び出されます。このフラグが設定されていない場合に、シグナルによってシステム・コールが中断されると、呼出しは失敗し、tperrno(5)TPGOTSIGが設定されます。
TPQCTL構造体
tpenqueue()の3番目の引数は、TPQCTL型の構造体へのポインタです。TPQCTL構造体には、アプリケーションで使用されるメンバーとOracle Tuxedoシステムで使用されるメンバーがあり、アプリケーション・プログラムとキュー式メッセージ機能間の両方向でパラメータがやり取りされます。tpenqueue()を呼び出すクライアントは、フラグを設定して、システム側で入力する必要のあるフィールドをマークします。この構造体は、tpdequeue()でも使用され、一部のフィールドは、アプリケーションがこの関数を呼び出すまで使用されません。リスト3-1は、この構造体全体を示しています。
リスト3-1 tpqctl_t構造体
#define TMQNAMELEN 127
#define TMMSGIDLEN 32
#define TMCORRIDLEN 32

struct tpqctl_t { /* control parameters to queue primitives */
long flags; /* indicates which of the values are set */
long deq_time; /* absolute/relative time for dequeuing */
long priority; /* enqueue priority */
long diagnostic; /* indicates reason for failure */
char msgid[TMMSGIDLEN]; /* ID of message before which to queue */
char corrid[TMCORRIDLEN]; /* correlation ID used to identify message */
char replyqueue[TMQNAMELEN+1]; /* queue name for reply message */
char failurequeue[TMQNAMELEN+1]; /* queue name for failure message */
CLIENTID cltid; /* client identifier for originating client */
long urcode; /* application user-return code */
long appkey; /* application authentication client key */
long delivery_qos; /* delivery quality of service */
long reply_qos; /* reply message quality of service */
long exp_time; /* expiration time */
};
typedef struct tpqctl_t TPQCTL;
 
以下は、tpenqueue()の入力情報を制御するflagsパラメータの有効なフラグです。
TPNOFLAGS
フラグおよび値は設定されません。制御構造体から情報は取得されません。構造体のフィールドに値を設定しないことは、TPNOFLAGSを設定することと同じです。
TPQTOP
このフラグを設定すると、キューの順序付けは無効になり、メッセージはキューの先頭に登録されます。このリクエストは、順序付けを無効にしてメッセージをキューの先頭に登録するようにキューが設定されているかどうかによって、使用できない場合があります。TPQTOPTPQBEFOREMSGIDは、相互に排他的なフラグです。
TPQBEFOREMSGID
このフラグを設定すると、キューの順序付けが無効になり、メッセージはctl->msgidによって識別されるメッセージの前に登録されます。このリクエストは、順序付けを無効にするようにキューが設定されているかどうかによって、使用できない場合があります。TPQTOPTPQBEFOREMSGIDは、相互に排他的なフラグです。メッセージ識別子の値は32バイト全体が意味を持つので、ctl->msgidで識別される値は、たとえばNULL文字を埋め込むなどして、完全に初期化する必要があります。
TPQTIME_ABS
このフラグが設定されていると、ctl->deq_timeで指定された時間の経過後、メッセージが処理されます。deq_timeは、使用しているアプリケーションで使用できる場合は、time(2)またはmktime(3C)、あるいはOracle Tuxedoシステムで提供されるgp_mktime(3c)によって生成される絶対時間値です。ctl->deq_timeに設定される値は、世界協定時(UTC) 1970年1月1日00:00:00から経過した秒数です。絶対時間は、キュー・マネージャ・プロセスが存在するマシン・クロックに基づいて設定されます。TPQTIME_ABSTPQTIME_RELは、相互に排他的なフラグです。
TPQTIME_REL
このフラグが設定されていると、キューへの登録が完了してからの相対時間の経過後、メッセージが処理されます。ctl->deq_timeは、キューへの登録が完了してから、送信されたメッセージが処理されるまでの遅延秒数を指定します。TPQTIME_ABSTPQTIME_RELは、相互に排他的なフラグです。
TPQPRIORITY
このフラグが設定されていると、リクエストがキューに登録されるときの優先度がctl->priorityに格納されます。優先度は、1から100以下の範囲である必要があります。優先度によって順序付けられたキューでは、数値が高いほど優先度も高くなり、高い数値のメッセージが低い数値のメッセージより先にキューから取り出されます。優先度によって順序付けられていないキューの場合、値は情報にすぎません。
このフラグを設定しなかった場合、メッセージの優先度はデフォルトの50になります。
TPQCORRID
このフラグが設定されていると、リクエストがtpdequeue(3c)>によってキューから取り出されるときに、ctl->corridに指定された相関識別子の値が使用されます。この識別子は、キューに登録されたすべての応答メッセージまたは異常終了メッセージに付加されるので、アプリケーションは応答を特定のリクエストに結び付けることができます。相関識別子の値は32バイト全体が意味を持つので、ctl->corridに指定される値は、たとえばNULL文字を埋め込むなどして、完全に初期化する必要があります。
TPQREPLYQ
このフラグが設定されていると、ctl->replyqueueに指定された応答キューが、キューに入れられたメッセージに関連付けられます。メッセージへの応答はすべて、リクエスト・メッセージと同じキュー・スペース内の、指定されたキューに登録されます。この文字列はNULLで終了する必要があります(長さは最大127文字)。サービスに対する応答が生成されても、応答キューが指定されていないか存在しない場合は、その応答は削除されます。
TPQFAILUREQ
このフラグが設定されていると、ctl->failurequeueに指定されている異常終了キューが、キューに入れられたメッセージに関連付けられます。(1)キューに登録されたメッセージがTMQFORWARD()によって処理され、(2) TMQFORWARD-dオプションで開始され、さらに(3)サービスが異常終了してNULL以外の応答を返す場合は、その応答と関連するtpurcodeによって構成される異常終了メッセージが、元のリクエスト・メッセージと同じキュー・スペース内で指定されたキューに登録されます。この文字列はNULLで終了する必要があります(長さは最大127文字)。
TPQDELIVERYQOSTPQREPLYQOS
TPQDELIVERYQOSフラグが設定されていると、ctl‑>delivery_qosで指定されたフラグにより、メッセージの配信サービスの品質が制御されます。その場合、相互に排他的な3つのフラグTPQQOSDEFAULTPERSISTTPQQOSPERSISTENTTPQQOSNONPERSISTENTのいずれかをctl‑>delivery_qosに設定しなければなりません。TPQDELIVERYQOSフラグが設定されていない場合、ターゲットのキューのデフォルトの配信ポリシーがメッセージに対するサービスの配信品質を指定します。
TPQREPLYQOSフラグが設定されていると、ctl‑>reply_qosで指定されるフラグが、メッセージの応答に対するサービスの品質を制御します。その場合、相互に排他的な3つのフラグTPQQOSDEFAULTPERSISTTPQQOSPERSISTENTTPQQOSNONPERSISTENTのいずれかをctl‑>reply_qosに設定しなければなりません。TPQREPLYQOSフラグは、TMQFORWARDによって処理されるメッセージから応答が返されるときに使用されます。サービスを呼び出すときにTMQFORWARDを使用しないアプリケーションでは、自身の応答メカニズムのヒントとしてTPQREPLYQOSフラグを使用できます。
TPQREPLYQOSが設定されていない場合、ctl‑>replyqueueキューのデフォルトの配信ポリシーが応答に対するサービスの配信品質を指定します。デフォルトの配信ポリシーは、メッセージに対する応答がキューに登録されるときに決定される点に注意してください。つまり、元のメッセージがキューに登録されてからメッセージに対する応答が登録されるまでの間に、応答キューのデフォルトの配信ポリシーが変更された場合、応答が最後に登録される時点で有効なポリシーが使用されます。
次は、ctl‑>delivery_qosctl‑>reply_qosの有効なフラグです。
TPQQOSDEFAULTPERSIST
このフラグは、ターゲットのキューで指定されているデフォルトの配信ポリシーを使用して、メッセージが配信されるように指定します。
TPQQOSPERSISTENT
このフラグは、メッセージがディスク・ベースの配信方法を使用して、永続的な記憶域に配信されることを指定します。このフラグが設定されていると、ターゲットのキューに指定されたデフォルトの配信ポリシーがこのフラグでオーバーライドされます。
TPQQOSNONPERSISTENT
このフラグは、メッセージがメモリー・ベースの配信方法を使用して、非永続的な記憶域に配信されることを指定します。特に、メッセージはキューから取り出されるまでメモリー内に登録されています。このフラグが設定されていると、ターゲットのキューに指定されたデフォルトの配信ポリシーがこのフラグでオーバーライドされます。呼出し側がトランザクション・モードの場合、非永続メッセージは呼出し側のトランザクション内でキューに登録されますが、システムがシャットダウンやクラッシュした場合、またはキュー・スペースとしてのIPC共有メモリーが削除された場合、非永続メッセージは失われます。
TPQEXPTIME_ABS
このフラグが設定されていると、メッセージに有効期限の絶対時間が適用されます。これは、キューからメッセージが削除される絶対時間です。
有効期限の絶対時間は、キュー・マネージャ・プロセスが存在するマシン・クロックによって決定されます。
有効期限の絶対時間は、ctl‑>exp_timeに格納された値で示されます。ctl‑>exp_timeの値は、time(2)mktime(3C)、またはgp_mktime(3c)によって生成された絶対時間、つまり世界協定時(UTC) 1970年1月1日00:00:00から経過した秒数に設定されなければなりません。
キューへの登録操作の時間より早い絶対時間が指定されると、操作は成功しますが、メッセージはしきい値の計算の対象になりません。有効期限の時間がメッセージの使用可能時間より前の場合、使用可能時間が有効期限の切れる時間より前になるようにいずれかの時間を変更しないかぎり、メッセージをキューから取り出すことはできません。また、これらのメッセージがキューからの取出しの対象になったことがなくても、有効期限が切れるとキューから削除されます。トランザクション内でメッセージの期限が切れた場合、それによってトランザクションが異常終了することはありません。トランザクション内でキューへの登録、またはキューからの取出し中に有効期限が切れたメッセージは、トランザクションが終了した時点でキューから削除されます。メッセージの有効期限が切れたことの通知は行われません。
TPQEXPTIME_ABSTPQEXPTIME_REL、およびTPQEXPTIME_NONEは、相互に排他的なフラグです。この3つのどのフラグも設定されていない場合、ターゲットのキューに対応しているデフォルトの有効期限の時間がメッセージに適用されます。
TPQEXPTIME_REL
このフラグが設定されていると、メッセージに有効期限の相対時間が適用されます。これは、メッセージがキューに到達してから、キューから削除されるまでの秒数です。有効期限の相対時間は、ctl‑>exp_timeに格納された値で示されます。
有効期限の時間がメッセージの使用可能時間より前の場合、使用可能時間が有効期限の切れる時間より前になるようにいずれかの時間を変更しないかぎり、メッセージをキューから取り出すことはできません。また、これらのメッセージがキューからの取出しの対象になったことがなくても、有効期限が切れるとキューから削除されます。トランザクション中にメッセージの期限が切れても、トランザクションが異常終了することはありません。トランザクション内でキューへの登録、またはキューからの取出し中に有効期限が切れたメッセージは、トランザクションが終了した時点でキューから削除されます。メッセージの有効期限が切れたことの通知は行われません。
TPQEXPTIME_ABSTPQEXPTIME_REL、およびTPQEXPTIME_NONEは、相互に排他的なフラグです。この3つのどのフラグも設定されていない場合、ターゲットのキューに対応しているデフォルトの有効期限の時間がメッセージに適用されます。
TPQEXPTIME_NONE
このフラグが設定されていると、キューのデフォルトのポリシーに有効期限の時間が含まれている場合でも、メッセージの有効期限が切れることはありません。
TPQEXPTIME_ABSTPQEXPTIME_REL、およびTPQEXPTIME_NONEは、相互に排他的なフラグです。この3つのどのフラグも設定されていない場合、ターゲットのキューに対応しているデフォルトの有効期限の時間がメッセージに適用されます。
また、TPQCTLurcodeフィールドにユーザー戻りコードを設定することができます。この値は、メッセージをキューから取り出すためにtpdequeue(3c)を呼び出すアプリケーションに返されます。
tpenqueue()からの出力では、次のフィールドがTPQCTL構造体に設定されます。
long flags; /* indicates which of the values are set */
char msgid[32]; /* ID of enqueued message */
long diagnostic; /* indicates reason for failure */
tpenqueue()からの出力情報を制御するflagsパラメータの有効なビットの一覧を次に示します。tpenqueue()の呼出し時にこのフラグがオンになっていると、/QサーバーTMQUEUE(5)は、構造体の対応する要素にメッセージ識別子を移入します。tpenqueue()の呼出し時にこのフラグ・ビットをオフにしていると、TMQUEUE()によって構造体の関連要素にメッセージ識別子は設定されません。
TPQMSGID
このフラグが設定されている場合に、tpenqueue()の呼出しが成功すると、メッセージ識別子がctl->msgidに格納されます。メッセージ識別子の値は32バイト全体が意味を持つので、ctl->msgidに格納される値は、たとえばNULL文字を埋め込むなどして、完全に初期化する必要があります。初期化に使用される実際の埋め込み文字は、Oracle Tuxedo /Qコンポーネントのリリースによって異なります。
制御構造体の残りのメンバーは、tpenqueue()への入力に使用されません。
tpenqueue()の呼出しが異常終了してtperrno(5)TPEDIAGNOSTICが設定された場合、失敗の原因を示す値がctl->diagnosticに返されます。可能な値は次のとおりです:
[QMEINVAL]
無効なフラグ値が指定されています。
[QMEBADRMID]
無効なリソース・マネージャ識別子が指定されました。
[QMENOTOPEN]
リソース・マネージャは現在オープンしていません。
[QMETRAN]
トランザクション・モードで、またはTPNOTRANフラグを設定して呼出しが行われ、キューにメッセージを登録するトランザクションの開始を試みたときに、エラーが発生しました。この診断は、Oracle Tuxedoリリース7.1以降のキュー・マネージャからは返されません。
[QMEBADMSGID]
無効なメッセージ識別子が指定されました。
[QMESYSTEM]
システム・エラーが発生しました。エラーの正確な性質がログ・ファイルに書き込まれます。
[QMEOS]
オペレーティング・システムのエラーが発生しました。
[QMEABORTED]
操作が中断されました。中断された操作がグローバル・トランザクション内で実行されていた場合、グローバル・トランザクションは「ロールバックのみ」とマークされます。それ以外の場合、キュー・マネージャは操作を中断します。
[QMEPROTO]
トランザクションの状態がアクティブではないときに、キューへの登録が行われました。
[QMEBADQUEUE]
無効または削除されたキューの名前が指定されています。
[QMENOSPACE]
キュー上に領域がないなどリソース不足が原因で、サービスの品質(永続的な記憶域または非永続的な記憶域)が指定されたメッセージがキューに登録されませんでした。次のいずれかのリソース設定を超えると、QMENOSPACEが返されます。(1)キュー・スペースに割り当てられたディスク容量(永続的)、(2)キュー・スペースに割り当てられたメモリー容量(非永続的)、(3)同時にアクティブ状態になるトランザクションの最大数(キュー・スペースで許容される数であることが必要です)、(4)キュー・スペースに一度に入れることができる最大メッセージ数、(5)キューイング・サービス・コンポーネントが処理できる並列アクションの最大数、または(6)キューイング・サービス・コンポーネントを同時に使用できる認証されたユーザーの最大数。
[QMERELEASE]
新機能がサポートされていないバージョンのOracle Tuxedoシステムのキュー・マネージャに対して、メッセージのキューへの登録が試みられました。
[QMESHARE]
指定されたキューのメッセージの登録時に、そのキューが別のアプリケーションによって排他的にオープンされています。Oracle Tuxedoシステム以外のOracle製品ベースのアプリケーションが、キューイング・サービスAPI (QSAPI)を使用して読取りおよび書込みを排他的に行うため、キューをオープンしています。
キューの順序の無効化
キューの作成時に、管理者がtpenqueue()呼出しでキュー上のメッセージの順序を無効にできるようにした場合、次の2つの方法でこの機能を利用できます。この2つの方法は、相互に排他的です。flagsTPQTOPを設定すると、メッセージをキューの先頭に置くことができます。または、flagsTPQBEFOREMSGIDctl->msgidに既存のメッセージのIDを設定して、メッセージを特定の既存のメッセージの前に置くこともできます。これは、前の呼出しからのメッセージIDがここで使用できるように保存されたことが前提になります。管理者は、キューでサポートされている方法を通知する必要があります。キューは、この2つのいずれかまたは両方を使用できるように、あるいはどちらも使用できないように作成できます。
キューの優先度の無効化
ctl->priorityに値を設定して、メッセージの優先度を指定することができます。この値は、1から100までの範囲でなければなりません。数値が高いほど優先度が高くなります。キューの順序付けパラメータの中にpriorityが含まれていない場合、ここで優先度を設定しても取出しの順序には影響しません。ただし、優先度の値は保持されるので、メッセージがキューから取り出されるときに検査されます。
メッセージの使用可能時間の設定
deq_timeに、絶対時間またはキューへの登録が完了してからの相対時間として、メッセージが処理されるまで時間を指定できます。flagsに、TPQTIME_ABSまたはTPQTIME_RELのいずれかを設定して、値の処理方法を指定できます。キューは、timeを順序付けの基準として作成することができます。その場合、メッセージは使用可能時間によって順序付けされます。
Oracle Tuxedo /Qには、gp_mktime(3c)関数が提供されています。この関数は、tm構造体の日付と時刻を1970年1月1日から経過した秒数に変換します。time(2)およびmktime(3C)関数をgp_mktime(3c)の代わりに使用することもできます。値は、time_t型(typedef'dで指定されたlong型)で返されます。キューからメッセージが取り出される絶対時間を設定するには、次の手順に従います。ここでは、2001年12月9日正午12:00を使用します。
1.
使用する日時の値をtm構造体に入力します。
#include <stdio.h>
#include <time.h>
static char *const wday[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "-unknown-"
};
struct tm time_str;
/*...*/
time_str.tm_year = 2001 - 1900;
time_str.tm_mon = 12 - 1;
time_str.tm_mday = 9;
time_str.tm_hour = 12;
time_str.tm_min = 0;
time_str.tm_sec = 1;
time_str.tm_isdst = -1;
2.
gp_mktimeを呼び出してdeq_timeに値を代入し、flagsを設定して絶対時間が提供されることを示します。
#include <atmi.h>
TPQCTL qctl;
if ((qctl->deq_time = (long)gp_mktime(&time_str)) == -1) {
/* check for errors */
}
qctl->flags = TPQTIME_ABS
3.
tpenqueue()を呼び出します。
if (tpenqueue(qspace, qname, qctl, *data,*len,*flags) == -1) {
/* check for errors */
}
キューからメッセージを取り出す相対時間、たとえば、キューへの登録操作が完了してからnnn秒などを指定する場合、deq_timeに秒数を指定し、flagsTPQTIME_RELを設定します。
tpenqueue()とトランザクション
tpenqueue()の呼出し側がトランザクション・モードにある場合に、TPNOTRANが設定されていないと、キューへの登録は呼出し側のトランザクション内で行われます。呼出し側は、tpenqueue()が成功したか失敗したかによって、メッセージがキューに登録されたかどうかを判断できます。呼出しが正常に行われると、メッセージがキューに登録されたことが保証されます。呼出しが失敗すると、メッセージがキューに登録された部分も含めて、トランザクションがロールバックされます。
tpenqueue()の呼出し側がトランザクション・モードにない場合、またはTPNOTRANが設定されている場合、メッセージは呼出し側のトランザクションとは別のトランザクションでキューに登録されます。tpenqueue()への呼出しが正常な戻り値を返した場合、メッセージがキューに登録されたことが保証されます。tpenqueue()の呼出しが通信エラーまたはタイムアウトによって失敗した場合は、その障害がメッセージ登録の前に発生したのか後に発生したのか、呼出し側には判断できません。
呼出し側がトランザクション・モードにないときにTPNOTRANを指定しても意味がありません。
メッセージのキューからの取出し
次は、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にビット設定を行うと、システムにtpdequeue()呼出しの処理方法が通知されます。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"
or
CLOPT = "-s TMQUEUE"
サーバー・グループQUE1のエントリには、OPENINFOパラメータを使用して、リソース・マネージャ、デバイスのパス名、およびキュー・スペース名を指定します。クライアント・プログラムにおけるqspace引数は、次のように記述されます。
if (tpdequeue("TMQUEUE", "REPLYQ", (TPQCTL *)&qctl,
(char **)&reqstr, &len,TPNOTIME) == -1) {
Error checking
}
「TMQUEUE(5)」リファレンス・ページの例では、サーバーを作成して構成ファイルで指定する際に、サービスの別名を指定する方法が示されています。A-1ページの「サンプル・アプリケーション」のサンプル・プログラムでも、サービスまたはキュー・スペース名の別名が指定されています。
tpdequeue(): qname引数
キュー・スペース内のキュー名は、そのキュー・スペースにアクセスするアプリケーション間で一貫していなければなりません。これは、応答キューでは特に重要です。qnameが応答キューを参照する場合、管理者はほかのキューと同じ方法で応答キュー、そして多くの場合、エラー・キューも作成します。qnameは、メッセージまたは応答を取り出すキューを指すポインタです。
tpdequeue(): dataおよびlen引数
この2つの引数は、tpenqueue()で使用される場合と若干意味が異なります。*dataは、キューから取り出されたメッセージをシステムが格納するバッファのアドレスを指します。tpdequeue()が呼び出された場合に、この値がNULLであることはエラーです。
tpdequeue()が戻ると、lenは取り出されたデータのデータ長情報を持つlong型を指します。0は応答にデータがなかったことを示します。アプリケーションによっては、これは正当で正常な応答です。長さ0の応答を受信した場合でも、それをキューに登録された要求の正常処理を示すために使用できます。バッファがtpdequeue()呼出しの前と比べて変更されているかどうかを確認する場合は、tpdequeue()呼出しの前にデータ長を保存し、それを呼出しが終了した後でlenと比較します。
tpdequeue(): flags引数
flagsの値は、tpdequeue()呼出しの処理方法をOracle Tuxedoシステムに通知するために使用されます。次は、有効なフラグです。
TPNOTRAN
呼出し側がトランザクション・モードにある場合に、このフラグが設定されていると、メッセージは呼出し側のトランザクション内ではキューから取り出されません。このフラグを設定するトランザクション・モードの呼出し側には、メッセージをキューから取り出すときにトランザクション・タイムアウトが適用され、それ以外は適用されません。キューからのメッセージの取出しが失敗した場合でも、呼出し側のトランザクションは影響されません。
TPNOBLOCK
ブロッキング状態が存在すると、メッセージはキューから取り出されません。このフラグが設定されている場合に、メッセージの転送先である内部バッファがいっぱいであるなどのブロッキング状態が存在すると、呼出しは失敗し、tperrno(5)TPEBLOCKが設定されます。このフラグが設定されていて、ターゲットのキューが別のアプリケーションによって排他的にオープンされているなどのブロッキング条件が存在する場合には、呼出しは失敗してtperrno()TPEDIAGNOSTICが設定され、TPQCTL構造体の診断フィールドはQMESHAREに設定されます。後者の場合、Oracle Tuxedoシステム以外のOracle製品に基づくほかのアプリケーションが、キューイング・サービスAPI (QSAPI)を使用して読取りと書き込み、またはそのいずれかを排他的に行うためにキューをオープンしています。
TPNOBLOCKが設定されていない場合に、ブロッキング状態が存在すると、その状態が解消されるかタイムアウト(トランザクション・タイムアウトまたはブロッキング・タイムアウト)が発生するまで、呼出し側はブロックされます。(TPQCTL構造体の) flagsTPQWAITオプションが指定されている場合は、このブロッキング条件には、キュー自体のブロッキングは含まれません。
TPNOTIME
このフラグを設定すると、呼出し側は無制限にブロックでき、ブロッキング・タイムアウトが適用されなくなります。ただし、トランザクション・タイムアウトは発生する可能性があります。
TPNOCHANGE
このフラグが設定されていると、*dataが指すバッファのタイプは変更されません。デフォルトでは、*dataが指すバッファとは異なるタイプのバッファが受信されると、受信側が着信バッファのタイプを識別するかぎり、*dataのバッファ・タイプは、受信されたバッファのタイプに変更されます。つまり、受信されたバッファのタイプとサブタイプは、*dataが指すバッファのタイプとサブタイプと一致する必要があります。
TPSIGRSTRT
このフラグが設定されていると、基底のシステム・コールがシグナルによって中断された場合、中断されたシステム・コールが再度呼び出されます。このフラグが設定されていない場合に、シグナルによってシステム・コールが中断されると、呼出しは失敗し、tperrno(5)TPGOTSIGが設定されます。
TPQCTL構造体
tpdequeue()の3番目の引数は、TPQCTL型の構造体へのポインタです。TPQCTL構造体には、アプリケーションで使用されるメンバーとOracle Tuxedoシステムで使用されるメンバーがあり、アプリケーション・プログラムとキュー式メッセージ機能間の両方向でパラメータがやり取りされます。tpdequeue()を呼び出すクライアントはフラグを設定して、システムで値が提供されるべきフィールドをマークします。前述のように、この構造体はtpenqueue()でも使用されます。一部のメンバーは、tpenqueue()だけに適用されます。この構造体全体のサンプル・コードは、3-5ページの「tpqctl_t構造体」に示されています。
tpdequeue()への入力では、次のフィールドをTPQCTL構造体に設定します。
long flags; /* indicates which of the values are set */
char msgid[32]; /* id of message to dequeue */
char corrid[32]; /* correlation identifier of message to dequeue */
次は、tpdequeue()の入力として有効なフラグです。
TPNOFLAGS
フラグは設定されません。制御構造体から情報は取得されません。
TPQGETBYMSGID
このフラグが設定されていると、ctl->msgidで識別されるメッセージ識別子を持つメッセージが取り出されることがリクエストされます。メッセージ識別子は、以前に呼び出されたtpenqueue()で決定されています。メッセージがあるキューから別のキューに移動された場合、メッセージ識別子は変更されます。メッセージ識別子の値は32バイト全体が意味を持つので、ctl->msgidで識別される値は、たとえばNULL文字を埋め込むなどして、完全に初期化される必要があります。
TPQGETBYCORRID
このフラグが設定されていると、ctl->corridで指定された相関識別子を持つメッセージを取り出すことがリクエストされます。相関識別子は、アプリケーションがtpenqueue()でキューにメッセージを登録したときに指定されます。相関識別子の値は32バイト全体が意味を持つので、ctl->corridに指定される値は、たとえばNULL文字を埋め込むなどして、完全に初期化する必要があります。
TPQWAIT
このフラグが設定されていると、キューが空の場合はエラーが戻されません。かわりに、メッセージを取り出せるようになるまで、プロセスは待機する必要があります。TPQWAITTPQGETBYMSGIDまたはTPQGETBYCORRIDとともに設定されている場合、指定されたメッセージ識別子または相関識別子を持つメッセージがキューに存在しないときは、エラーが戻されません。かわりに、基準を満たすメッセージを取り出せるようになるまで、プロセスは待機する必要があります。プロセスには呼出し側のトランザクション・タイムアウトが適用されますが、トランザクション・モードではない場合、TMQUEUEプロセスで-tオプションで指定されたタイムアウトが適用されます。
要求する基準を満たすメッセージがすぐには利用できず、設定されたアクションのリソースを使い尽くしてしまった場合には、tpdequeue() は-1を返し、tperrno()TPEDIAGNOSTICに設定し、TPQCTL構造体の診断フィールドをQMESYSTEMに設定します。
TPQWAIT制御パラメータを指定するtpdequeue()の各リクエストでは、条件を満たすメッセージがすぐに利用できない場合、キュー・マネージャ(TMQUEUE)のアクション・オブジェクトを使用できる必要があります。アクション・オブジェクトが使用できない場合、tpdequeue()リクエストは失敗します。利用できるキュー・マネージャのアクション数は、キュー・スペースの作成時または変更時に指定されます。待機中のキューからの取出しリクエストが完了すると、対応するアクション・オブジェクトは別のリクエストに使用できるようになります。
TPQPEEK
このフラグが設定されていると、指定されたメッセージが読み取られてもキューから削除されません。TPNOTRANフラグも設定する必要があります。
あるスレッドがTPQPEEKを使用してメッセージを破棄せずにキューから取り出す場合、その取出しリクエストをシステムが処理している短時間の間、非ブロッキング状態の他のメッセージ取出し操作にメッセージが認識されないことがあります。たとえば、特定の選択基準(メッセージ識別子や相関識別子など)を使用してメッセージをキューから取り出す操作が、破棄せずに取出しが現在行われているメッセージを探している場合などがあります。
次は、tpdequeue()からの出力情報を制御するflagsパラメータの有効なビットです。どのフラグ・ビットでも、tpdequeue()の呼出し時にオンになっていると、メッセージがキューに登録されたときに提供された値が、構造体の対応するフィールド(3-5ページの「tpqctl_t構造体」を参照)に移入され、そのビットは設定されたままになります。値が使用できない(つまり、メッセージがキューに登録されたときに値が指定されなかった)場合、またはtpdequeue()を呼び出したときにビットが設定されなかった場合、tpdequeue()はフラグがオフの状態で完了します。
TPQPRIORITY
このフラグが設定され、tpdequeue()の呼出しが成功し、メッセージが明示的な優先度でキューに登録された場合、その優先度はctl->priorityに格納されます。優先度は1以上100以内の範囲内で、数値が高いほど優先度も高くなります。つまり、高い数値のメッセージが低い数値のメッセージよりも先にキューから取り出されます。優先度によって順序付けられていないキューの場合、値は情報にすぎません。
メッセージがキューに登録されるときに優先度が明示的に指定されずにtpdequeue()呼出しが正常に終了した場合、このメッセージの優先度は50になります。
TPQMSGID
このフラグが設定されている場合に、tpdequeue()の呼出しが成功すると、メッセージ識別子がctl->msgidに格納されます。メッセージ識別子の値は、32バイト全体が意味を持ちます。
TPQCORRID
このフラグが設定され、tpdequeue()の呼出しが成功し、メッセージが相関識別子によってキューに登録されていた場合、相関識別子がctl->corridに格納されます。相関識別子の値は、32バイト全体が意味を持ちます。Oracle Tuxedo /Qが提供するメッセージの応答には、すべて元のリクエスト・メッセージの相関識別子が付いています。
TPQDELIVERYQOS
このフラグが設定され、tpdequeue()の呼出しが成功し、メッセージがサービスの配信品質とともにキューに登録されていた場合、TPQQOSDEFAULTPERSISTTPQQOSPERSISTENT、またはTPQQOSNONPERSISTENTフラグがctl‑>delivery_qosに格納されます。メッセージがキューに登録されたときに配信サービスの品質が明示的に指定されていない場合は、ターゲットとなるキューのデフォルトの配信ポリシーによってメッセージ配信の品質が決まります。
TPQREPLYQOS
このフラグが設定され、tpdequeue()の呼出しが成功し、メッセージがサービスの応答品質とともにキューに登録されていた場合、TPQQOSDEFAULTPERSISTTPQQOSPERSISTENT、またはTPQQOSNONPERSISTENTフラグがctl‑>reply_qosに格納されます。メッセージがキューに登録されていたときに応答のサービス品質が明示的に指定されていない場合、ctl‑>replyqueueキューのデフォルトの配信ポリシーによって、すべての応答に対する配信サービスの品質が決まります。
デフォルトの配信ポリシーは、メッセージに対する応答がキューに登録されるときに決定される点に注意してください。つまり、元のメッセージがキューに登録されてからメッセージに対する応答が登録されるまでの間に、応答キューのデフォルトの配信ポリシーが変更された場合、応答が最後に登録される時点で有効なポリシーが使用されます。
TPQREPLYQ
このフラグが設定され、tpdequeue()の呼出しが成功し、メッセージが応答キューと共にキューに登録されていた場合、その応答キューの名前がctl->replyqueueに格納されます。メッセージへの応答は、リクエスト・メッセージと同じキュー・スペース内の指定された応答キューに登録されます。
TPQFAILUREQ
このフラグが設定され、tpdequeue()の呼出しが成功し、メッセージが異常終了キューと共にキューに登録されていた場合、その異常終了キューの名前がctl->failurequeueに格納されます。失敗メッセージは、リクエスト・メッセージと同じキュー・スペース内の指定された失敗キューに登録されます。
flagsパラメータの残りのビットは、tpdequeue()が呼び出されるとクリア(0に設定)されます。これには、TPQTOPTPQBEFOREMSGIDTPQTIME_ABSTPQTIME_RELTPQEXPTIME_ABSTPQEXPTIME_REL、およびTPQEXPTIME_NONEが含まれます。これらのビットは、tpenqueue()の入力情報を制御するflagsパラメータの有効なビットです。
tpdequeue()の呼出しが失敗し、tperrno(5)TPEDIAGNOSTICが設定された場合は、失敗の原因を示す値がctl->diagnosticに返されます。ctl->diagnosticの有効なコードには、3-5ページの「TPQCTL構造体」に示されているtpenqueue()の値(QMENOSPACEQMERELEASEを除く)の他に、次のものがあります。
[QMENOMSG]
キューから取り出せるメッセージはありません。メッセージがキュー上に存在し、別のアプリケーション・プロセスがこのメッセージをキューから読み取った可能性があることに注意してください。この場合、その別のプロセスがトランザクションをロールバックしたときに、メッセージはキューに戻されます。
[QMEINUSE]
メッセージ識別子または相関識別子を使用してメッセージをキューから取り出す際に、指定されたメッセージが別のトランザクションによって使用されています。それ以外の場合、現在キューにあるすべてのメッセージは、ほかのトランザクションによって使用されています。この診断は、Oracle Tuxedoリリース7.1以降のキュー・マネージャからは返されません。
TPQWAITの使用
TPQCTL構造体のflagsTPQWAITが設定されてtpdequeue()が呼び出された場合に、メッセージをすぐに取り出すことができないと、tpdequeue()が呼出し側に制御を戻す前に、TMQUEUEサーバーはtpdequeue()リクエストに一致するメッセージがキューに到着するのを待ちます。TMQUEUEプロセスは待機中のリクエストを無視し、他のプロセスのリクエストを処理しながら、最初のリクエストの条件が満たされるのを待ちます。TPQGETBYMSGIDTPQGETBYCORRIDも指定されている場合、サーバーは指定されたメッセージ識別子や相関識別子を持つメッセージをキューから取り出せるようになるまで待ちます。このどちらのフラグも設定されていない場合、サーバーは任意のメッセージがキューに登録されるまで待ちます。呼出し側がトランザクション・モードの場合、サーバーの待機時間は、呼出し側のトランザクション・タイムアウトによって制御されますが、呼出し側がトランザクション・モードでない場合、TMQUEUEサーバーのCLOPTパラメータに指定される-tオプションで制御されます。
TMQUEUEサーバーは、リクエストを処理するアクション・リソースを利用できるかぎり、複数の待機中tpdequeue()リクエストを同時に処理できます。十分なアクション・リソースがキュー・スペースに対して設定されていない場合、tpdequeue()は失敗します。使用しているシステムがこれに該当する場合は、キュー・スペースに対するアクション・リソースの数を増やしてください。
TMQFORWARDサービス使用時のエラー処理
キューからのメッセージの取出しで、エラー処理の最良の方法を考慮する場合、次の2種類のエラーを区別しておきます。
リクエストされたサービスに転送するために、TMQFORWARD(5)がメッセージをキューから取り出すときに発生するエラー
リクエストを処理するサービスに発生するエラー
デフォルトでは、メッセージがトランザクション内でキューから取り出され、そのトランザクションがロールバックされるとき(retryパラメータが0より大きい場合は)、メッセージがキューに戻されて、再度取出しと実行が可能になります。一時的な障害が解消されるように(たとえば、データベースのロックを別のトランザクションが解除するように)少し時間をおいてから、メッセージの取出しと実行を再度試みます。通常、再試行の回数に上限を設定することも、アプリケーション不備によってリソースを著しく浪費することを防ぐために有用です。管理者がキューを設定するときに、再試行の回数と遅延時間(秒単位)の両方を指定できます。再試行の回数0は、再試行が行われないことを示します。再試行の回数が上限に達すると、管理者がキュー・スペースに設定するエラー・キューにメッセージが移動されます。エラー・キューが構成されていない場合、再試行回数に達したメッセージは削除されます。エラー・キューのメッセージは管理者が処理する必要があります。このとき、アプリケーションの要件を満たすように発信元への通知方法を検討します。選択されたメッセージ処理方法は、メッセージをキューに登録した発信元プログラムにほとんど透過的です。メッセージは一度正常にキューに登録されると、tpenqueue()のパラメータおよびキューの属性に従って処理されることが実質的には保証されます。メッセージがエラー・キューに移動されたことの通知は、キューのパラメータを適切に調整されたシステムではほとんどありません。
異常終了キュー(通常、キュー・スペースのエラー・キューとは異なります)は、キューに登録された各メッセージと関連付けられます。このキューは、異常終了メッセージを置く場所として、キューにメッセージを登録する呼出しで指定されます。特定のリクエストに対する異常終了メッセージは、アプリケーション生成の相関識別子で識別できます。相関識別子は、キューにメッセージを登録するときに、そのメッセージと関連付けられます。
成功するまで(または事前に定義された回数まで)再試行を繰り返すというデフォルトの動作は、時間が経過すれば解決されるような一時的な障害が失敗の原因であり、メッセージが後から適切に処理される場合は適しています。
障害が一時的なものではない場合もあります。たとえば、存在しないアカウントでの操作をリクエストするメッセージがキューに入れられている場合(アプリケーションも適当な時間に存在していない場合)です。その場合、再試行してリソースを浪費しないようにします。アプリケーション・プログラマまたは管理者が、特定の操作の失敗が一時的ではないと判断した場合、単に再試行回数を0に設定します。ただし、この場合、このようなメッセージが入るキュー・スペースのエラー・キューを継続的にクリアするメカニズム(キューを定期的に読み取るバックグラウンドのクライアントなど)が必要です。また、同じサービスに対する障害でも、一時的なもの(データベース・ロックの競合など)であったり、永続的なもの(アカウントが存在しないなど)であったりする場合が多くあります。
メッセージがTMQFORWARDによって処理される(キューから取り出され、tpcall()を介してアプリケーションに渡される)場合、tpcall()が返す情報には、TPESVCFAILエラーが一時的な障害と永続的な障害のどちらによって生じたものであるかを示すメカニズムはありません。
キューからの取出しをアプリケーションが処理する場合、簡単な解決方法はたとえ操作が失敗しても、そのサービスに対して成功を返すことです。つまり、TPSUCCESSを設定してtpreturnを実行します。これにより、トランザクションはコミット可能になり、メッセージはキューから削除されます。応答メッセージが使用されている場合、サービスから返されるバッファの情報によって操作の失敗を示すことができ、メッセージが応答キューに登録されます。tpreturnrcode引数も、アプリケーション固有の情報を返すために使用できます。
サービスが失敗し、トランザクションをロールバックする必要がある場合、TMQFORWARDが処理をそれ以上行わずに、2番目のトランザクションを実行してキューからメッセージを削除するかどうかは明確ではありません。デフォルトでは、TMQFORWARDは失敗したサービスに対するメッセージを削除しません。TMQFORWARDのトランザクションはロールバックされ、メッセージはキューに格納されます。TMQFORWARDにコマンド行オプションを指定すると、サービスが失敗して0より長い応答メッセージが返された場合に、メッセージがキューから削除されます。メッセージは、2番目のトランザクションで削除されます。この処理を行うには、キューに遅延時間および再試行回数を設定する必要があります。メッセージが失敗したキューに関連付けられている場合、メッセージがキューから削除されたトランザクションと同じトランザクションで、応答データが異常終了キューに登録されます。
TMQFORWARDを通して呼び出されたサービスからの応答をキューから取り出す手順
アプリケーションがキューに登録されたメッセージに対する応答を要求している場合、次の手順に従います。
1.
前提条件として、キュー・スペースに応答キューおよび異常終了キューがあることが必要です。アプリケーションは、相関識別子の内容について一貫していなければなりません。サービスは、論理的な失敗の場合にTPSUCCESSを返し、tpreturnrcode引数に情報を示すコードを返すようにコーディングします。
2.
tpenqueue()を呼び出してキューにメッセージを登録する際に、次のフラグ・ビットがオンになるようにflagsを設定します。
TPQCORRID TPQREPLYQ
TPQFAILUREQ TPQMSGID
この呼出しを行う前に、corridreplyqueue、およびfailurequeueの値を設定します。呼出しから制御が戻ったら、corridを保存します。
3.
tpdequeue()を呼び出して応答を確認する際に、qname引数に応答キューを指定し、次のフラグ・ビットがオンになるようにflagsを設定します。
TPQCORRID TPQREPLYQ
TPQFAILUREQ TPQMSGID
TPQGETCORRID
この呼出しを行う前に、保存した相関識別子を使用してcorridに入力します。tpdequeue()の呼出しが失敗し、tperrno(5)TPEDIAGNOSTICが設定された場合、詳しい情報をdiagnosticから取得できます。エラー・コードQMENOMSGを受信した場合、キューから取り出すことのできるメッセージがなかったことを示します。
4.
もう1つのtpdequeue()呼出しを設定します。この呼出しでは、qnameが異常終了キューの名前を指し、次のフラグ・ビットがオンになるようにflagsを設定します。
TPQCORRID TPQREPLYQ
TPQFAILUREQ TPQMSGID
TPQGETBYCORRID
corridに相関識別子を挿入します。呼出しから制御が戻ったら、lenを調べてデータが受信されたかどうかを確認し、また、urcodeを調べてサービスがユーザー戻りコードを返したかどうかを確認します。
メッセージの順次処理
メッセージの順次処理は、あるサービスがそのトランザクションがコミットされる前に、連鎖的に次のサービス用にメッセージをキューに登録することによって行われます。最初の発信元のプロセスは、reply_queueに対する一連のtpdequeue()呼出しによって順次処理の進行状況を追跡できます。ただし、各メンバーが同じ相関識別子を使用し、長さ0の応答を返すことが必要です。
また、非請求通知を使用して、順次処理全体が成功したという通知を最初の発信元に返すこともできます。順次処理の最後のトランザクションがtpcommitで終了したことを確認するには、tpdequeue()から戻されたTPQCTL構造体、またはサービスに渡されたTPSVCINFO構造体で渡されるクライアント識別子を使用して、tpnotifyを呼び出す操作を追加します。最初の発信元であるクライアントは、tpsetunsolを呼び出して、使用されている非請求メッセージ・ハンドラを指定しておかなければなりません。
ピア・ツー・ピア通信でのキューの使用
キューへのメッセージの登録およびキューからのメッセージの取出しに関するこれまでの説明では、キューがリクエスト/レスポンスの一形態として使用されていることが暗黙の前提になっていました。メッセージ自体はサービス・リクエストである必要はありません。キュー式メッセージ機能は、あるプロセスから別のプロセスに、サービス・リクエストと同じように効果的にデータを転送できます。アプリケーション間またはクライアント間のこの通信方式は、ピア・ツー・ピア通信と呼ばれます。
使用するアプリケーションが、このような目的でOracle Tuxedo /Qを使用することに適している場合は、管理者に別のキューを作成してもらい、そのキューからメッセージを取り出す独自の受信用プログラムをコーディングします。

Copyright ©1994, 2017,Oracle and/or its affiliates. All rights reserved