flags)
qspace: QUEUE SPACE的名称 qname: QUEUE的名称
ctl: 指向TMQCTL的指针
data: 要发送到名为QNAME的QUEUE的数据所对应的缓冲区 len: DATA缓冲区的长度
flags: 与TPCALL的设置相同,要注意的是TPNOTRAN
如果设置了TPNOTRAN,并不是说该调用不处于事务模式,只是表明
如果调用tpenqueue()的程序已处于事务模式中,那么tpenqueue()将单独启一个
事务.
TPQCTL中flag的值可以为:
TPNOFLAGS: 不对TPQCTL中的各字段进行设置,让它们采用默认值.
TPQTOP: 把该消息放在该QUEUE的顶部,使该消息最先被取出,在创建该
QUEUE时,当指定out-of-order enqueuing时,TOP选项必须被选上才行.
TPQBEFOREMSGID:把该消息放在MSGID为TPQCTL中的MSGID域指定的MSGID 所对应的消息之前.在创建该QUEUE时,当指定out-of-order enqueuing时,MSGID
选项必须被选上才行. TPQTIME_ABS:只有到了TPQCTL中的DEQ_TIME域指定的时间之后,该消息才能被取出.
TPQTIME_REL:只有从当前开始过了TPQCTL中的TPQTIME_REL域指定的时间之后,该消息才能
被取出.
TPQPRORITY:设置该消息的优先级,在TPQCTL中的TPQPRORITY域指定,范围为0-100
TPQCORRID: 如果该标志被设置,那么在进行tpdequeue()时,可以取出corrid=ctl-->corrid
的MESSAGE
TPQREPLYQ: 把该消息的处理结果放在TPQCTL中的TPQREPLYQ域指定的QUEUE中. TPQFAILUREQ:把该消息的处理结果放在TPQCTL中的TPQFAILUREQ域指定的QUEUE中.
如果tpenqueue()调用成功,在TPQCTL中的TPQMSGID域中返回该消息所对应的MSGID
tpenqueue()与事务:
如果调用 tpenqueue()的程序当前处于事务模式,并且tpenqueue()中的FLAGS参数没有设置TPNOTRAN,那么tpenqueue()处于当前事务中,如果该事务成功提交,那么tpenqueue()中发送的消息一定在QUEUE中, 如果该事务成功提交,那么tpenqueue()中发送的消息一定不会在QUEUE中
如果调用 tpenqueue()的程序当前不处于事务模式,或者tpenqueue()中的FLAGS参数设置了TPNOTRAN,那么tpenqueue()不处于当前的事务中,如果tpenqueue()返回成功,那么tpenqueue()中发送的消息一定在QUEUE中, 如果,那么tpenqueue()因为网络故障或事务超时而返回失败,那么调用tpenqueue()的程序将不能中发送的消息一定不会在QUEUE中
tpdequeue()
int tpdequeue (char *qspace, char *qname, TPQCTL *ctl,char **data, long *len, long flags)
从名为QNAME的QUEUE中取出一条消息.
qspace: QUEUE SPACE的名称 qname: QUEUE的名称
ctl: 指向TMQCTL的指针
data: 把该消息中的数据保存到该缓冲区中. len: 该消息中数据的长度
flags: 与TPCALL的设置相同,要注意的是TPNOTRAN
如果设置了TPNOTRAN,并不是说该调用不处于事务模式,只是表明 如果调用tpenqueue()的程序已处于事务模式中,那么tpenqueue() 将单独启一个事务.
TPQCTL中的flags的设置:
TPNOFLAGS: 不对TPQCTL中的各字段进行设置,让它们采用默认值. TPQGETBYMSGID: 从队列qname中取msgid=TPQCTL->msgid的消息
TPQGETBYCORRID: 从队列qname中取corrid =TPQCTL-> corrid的消息 TPQWAIT:
如果qname中没有消息,调用tpdequeue ()的进程要阻塞在那里,直到有 qname中有可以被取出的消息为止.
根据取出的消息的属性,TUXEDO自动为下面的字段赋值: TPQPRIORITY: 取出的消息的优先级 TPMSGID: 取出的消息的msgid TPQCORRID: TPQREPLYQ: TPQFAILUREQ:
取出的消息的corrid
取出的消息所对应的reply queue的名字 取出的消息所对应的failure queue的名字
10.4 一个简单的例子
qsample(在$TUXDIR/APPS/QSAMPLE目录下)是TUXEDO用于演示/Q的例子,客户机将一个包含字符串的消息放入STRING队列中,TMQFORWARD将该消息转发到STRING服务,要求它将消息体内的字符串转换成大写。处理完毕后,TMQFORWARD把响应消息放入响应队列RPLYQ,客户机再从RPLYQ中取出响应消息,进行打印输出。
qsample的服务端程序
服务端程序server.c的内容如下 #include
STRING(msg) TPSVCINFO *msg; {
char *str; int i;
/* set pointer to data portion of message */ str = (char *)msg->data;
/* convert string to upper case */ for (i = 0; i < msg->len; i++) { str[i] = toupper(str[i]);
}
/*通过tpreturn函数将转换结果传回给TMQFORWARD服务器,并表明转换成功*/
tpreturn(TPSUCCESS, 0, msg->data, 0L, 0); }
设置环境变量
除了设置QMCONFIG外,还需要根据实际情况设置:TUXDIR(Tuxedo的安装目录)、APPDIR和TUXCONFIG环境变量。
创建消息队列
qsample用到了一个队列空间QSPACE和三个队列STRING、RPLYQ与errque。在NT平台下创建它们的最好办法是使用nmake命令,即“c:\\qsample\\nmake/f qsapme.nt QUE”,当然也可以手工创建。
创建事务日志
TMS_QM在队列事务管理时,需要用到日志设备,创建办法也是用nmake命令: c:\\qsample\\nmake/f qsapme.nt TLOG
它执行了qsample.nt中预定义的一组Tuxedo命令。
qsample的客户程序
客户程序client.c的流程是:加入Tuxedo系统→消息入队→消息出队→退出系统。simpapp直接通过tpcall()函数调用TOUPPER服务,而qsample则将消息放入队列STRING,由TMQFORWARD服务器通过tpcall()调用STRING服务。 #include
int main(int argc char **argv) {
char *reqstr; long len; TPQCTL qctl;
/* string to be sent */ /* Q control structures */ /* length of return string */
/* join the application */
if (tpinit(NULL) == -1) { (void) fprintf(stderr,\ tpstrerror(tperrno)); exit(1); }
/* get request buffer */
if ((reqstr = tpalloc(\ (void) fprintf(stderr,\ tpstrerror(tperrno)); exit(1); }
(void) strcpy(reqstr,\(void) printf(\
/* set flag in control structure indicating a reply queue */ qctl.flags = TPQREPLYQ;
/* provide name of reply queue in control structure */ (void) strcpy(qctl.replyqueue, \
if (tpenqueue(\
0, 0) == -1) {
(void) fprintf(stderr,\ tpstrerror(tperrno)); if (tperrno == TPEDIAGNOSTIC) { (void) fprintf(stderr,\ qctl.diagnostic); }
tpfree((char *)reqstr);
}
}
(void) tpterm(); exit(1);
/* set flag indicating we will wait for a reply */
qctl.flags = TPQWAIT;
if (tpdequeue(\
&len, TPNOTIME) == -1) {
(void) fprintf(stderr,\ }
tpstrerror(tperrno));
(void) fprintf(stderr,\
qctl.diagnostic);
if (tperrno == TPEDIAGNOSTIC) {
tpfree(reqstr); (void) tpterm();
exit(1); }
(void) printf(\/* clean up and exit */ tpfree(reqstr); (void) tpterm(); return(0);
修改配置文件
配置文件ubb.sample定义了三个SERVER:server、TMQUEUE、TMQFORWARD和两个组:GROUP1和QUE1。SERVER提供STRING服务,TMQUEUE和TMQFORWARD属于QUE1组。QUE1组中的OPENINFO参数定义了队列资源管理器TUXEDO/QM、队列设备和队列空间。最后一行CLOPT参数中定义了将消息转发给STRING服务。
*RESOURCES IPCKEY 61234 DOMAINID MASTER MODEL
*MACHINES
DEMO LMID = SITE1 TUXDIR =\
APPDIR = \
TUXCONFIG = \ TLOGDEVICE =\
qsample SITE1 SHM