版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 ATMI及编程模型 编程涉及到的环境 类型缓冲区 编写客户机程序 编写服务器程序 编写请求/响应程序 编写会话程序 编写带全局事务的服务器 使用TMIB维护和监控系统ATMI(Application to Transation Monitor Interface 应用到事务监视器接口) 是Tuxedo为客户实施分布式应用提供一套C函数。ClientServer1Database1Server2Database2tpinittpcalltpbegintpcommittpreturntpforwardRMTMApplication 请求/响应模型最基本的通信方式,客户机发起请求,服务器进程处理完
2、请求后将响应返回客户机。此时,该交互即完成。其中异步是基本的方式: tpcall = tpacall + tpgetrplyServerClienttpcallservice_fun() tpreturnServerClienttpacall做一些事情tpgetrplyservice_fun() tpreturnServer1Clienttpcallservice_fun1() tpcall tpforward 此处代码会执行!service_fun2() tpreturn()Server2service_fun3() tpreturn()Server3 会话模型先建立起连接(即客户进程与服务
3、进程建立起协作关系),然后在该连接上进行多次交互。该模式是有状态的,因为服务进程的上下文在会话结束之前一直保持。ServertpconnectClienttpdiscontpsendtprecvtpsendtprecv上下文N次交互 消息通知前面的方式中,服务器是被动的(处理过程需要由客户机发起)。如果服务器要主动给客户发消息,就要用到消息通知。ServerClient注册的消息处理器tpnotify/tpbroadcast 事件代理Tuxedo有一个事件代理服务器,客户机和服务器可以通过它订阅或发布事件。事件代理tpsubscribe事件处理器Server/ClienttppostServe
4、r/Client/Q大型应用的一次交易处理一般会涉及与多个服务器交互(多层结构),服务器的协作方式主要有三种: 嵌套调用在服务内部调用另一个交易。除非必须使用,不建议采用此方式。该模式形成一个服务器调用链,所有链上的服务器在交易结束之前不能再处理其它请求。 转发推送tpcall(client) tpforward(1.N) tpreturn(last) 异步推送tpacall_no_reply(client)tpacall_no_reply(1.N) endtpcallEAI适配层forward分派层forward交易处理层tpacalltpacalltpacallEND从总线取出请求将响应放
5、入总线 推送是无状态的,效率高,重入时要设法恢复它的运行上下文。 嵌套会占用更多的进程,并发性会降低,但调用者的上下文不会丢失。flowS1S2Local ServerRomte Serversave ctx tpacall tpcalltpacall callbackload ctxS2Storage 如果有执行状态返回,-1表示失败。 查看出错信息在调用API时都有类似如下的出错检测代码:if (tpacall(TUX_SVC, send_buf, (long)send_len, TPNOREPLY) = -1) userlog(tpacall失败: errno=%d, msg=%s,tp
6、errno, tpstrerror(tperrno);tpfree(text);return -1; 编程相关的UBB参数 编写会话服务器,要在Servers节中指示是个会话服务器(CONV=Y) 使用工作站客户端要在Machines节中指定MAXWSCLINETS的数量 存在着大量与编程密切相关的UBB参数(参见用C写ATMI应用第二章),系统配置与编程在此产生了较强的耦合。 特定用途的环境变量 使用VIEW32视图:VIEWDIR32、VIEWFILES32 使用FML32视图:FLDTBLDIR32、FIELDTBLS32 编译器应采用与操作系统渊源最深的编译系统,因为buildserv
7、er对编译器是由针对性的。 AIX 使用XLC C/C+ Windows使用Visual C+ Linux使用gcc HP-UX 使用aCC/aC+ 头文件 atmi 重要的头文件,含ATMI接口定义,声明公开的函数与常量宏 fml.h/fml32.h 定义了操作FML的函数与常量 tpadmin.h 定义TMIB接口的函数 userlog.h 用户日志接口(用于生成ULOG日志文件) Tuxedo程序库Tuxedo程序库信息由buildserver/buildclient自动附加到编译命令行上,用户一般不用关心。所有库都在$TUXDIR/lib目录下。 libtmib.a TMIB库,使用t
8、padmcall时要包含此库 libtux.a Tuxedo主函数库,大部分函数都在此库中 libfml.a/libfml32.a 操作FML/FML32的函数库 lengine.a 平台上的一些公共例程,如安全、线程管理、消息转换等注:不知道函数在什么库中时,可用nm命令去寻找。 缓冲区的种类 分配缓冲区 释放缓冲区 改变缓冲区的大小 数据操作(各类型缓冲区有自己的操作方法) VIEW/VIEW32 FML/FML32 XML 类型缓冲区是带类型说明的内存块,它的引入给开发者增加一些额外的负担,但这是值得的: 类型缓冲区为异质系统建立了一个中间层,当与目标系统通信时,调用者与接收者只需考虑类
9、型缓冲区而不用考虑目标主机的数据结构(机器字节数、对齐方式、字节顺序、字符编码) 附加的好处:类型缓冲区都是动态内存(从堆上分配),使用类型缓冲区也便于系统集中管理动态内存(分配、释放、优化等),减少内存出错的机率。 类型缓冲区之间的比较可以从如下几个方面进行: 是否是自描述的。自描述的缓冲区在tpcall、tpreturn中可不指定它的大小。 有无子类型。 是否支持DDR。根据缓冲区中的某些数据项的值,按指定的标准将请求路由到不同的服务器组上。支持DDR的缓冲区一定是带成员的聚集,并且可以按成员名称访问。 是否存在编码、解码。不存在时,传输效率高,但异质支持差 CARRAY一个内存块,就如用
10、malloc分配的一样。它不知道自己有多大,需要有其它变量指示它的大小。它效率最高,因为它不编码/解码。CARRAY主要用来转输一个内存块。 FML/FML32是一种自描述的缓冲区,每个数据域都有标识号、长度等信息。FML只通过函数进行操作,因而有很好的灵活性(带来类似于用对象方法代替直接操作数据域的好处)。它支持DDR,一般的DDR实现都是基于FML的。 STRING是C的字符串类型,以0作为结束符。但它是支持编码与解码的。它显然不能支持类似UTF16这样的宽字符集的串(这时应使用MBSTRING),如果必须使用STRING来传递UTF-16的话,可先转换为UTF-8后再传输。 VIEW/V
11、IEW32VIEW就是C结构同义词,只是为了实现异构系统之间的数据交换而需要做一些额外的工作。一些工作是开发者做的,另一些是系统内部做的。结构可以按字段访问的,因而可以DDR。 XML与CARRAY差别不大。XML比CARRAY多一点的功能是,告诉大家“我的内容是一个XML文档”。XML支持DDR,但代价远比FML与VIEW大。 MBSTRING是支持多字节字符编码的串,这样的串不再是与C兼容,不能用中的函数来操作它们。它的头部包含有字符集信息。 缓冲区是动态内存,使用前必须用tpalloc函数分配。 原型:char* tpalloc(char* type,/* 类型名:如STRING,XML
12、*/char* subtype,/* 子类型,适用FML/VIEW*/long size)/* 大小 0, =0为缺省大小 */ 返回值。成功返回缓冲区指针,失败返回NULL(0), 虽然分配的失败机会很少,但返回值必须测试是否为NULL! 例:char* buf = tpalloc(“STRING”,0,0); 注:Tuxedo形成较早,char*多数是指void*。 缓冲区可以更改大小,大小更改后,返回的地址可能上新的地址,以后使用新的地址,而不能再用分配前的地址。 原型:char* tprealloc(char* ptr,/* 缓冲区指针 */long size)/* 新的大小*/注意:
13、返回值不一不等于ptr!不建议使用tprealloc,好的办法是分配新尺寸的缓冲区,从原缓冲区复制数据到新缓冲区,删除原缓冲区。该函数比较凶险,使用不当有可能导致内存泄漏。 缓冲区可以测定它的类型、子类型和大小。 原型: 原型:long tptypes(char* ptr,/* 缓冲区指针 */char* type, /* 主类型 */char* subtype)/* 子类型 */ 返回值:缓冲区的大小,失败返回-1 注意:type的长度为8, subtype的长度为16 与malloc函数一样,tpalloc分配的缓冲区使用之后也需要释放。 原型:void tpfree(char* ptr/
14、* 缓冲区指针 */) 注意:tpforward,tpreturn传入的缓冲区是在这些函数内部释放,因为用户此时已失去了控制权。其它场合一律要释放(如在tpacall/tpcall使用之后),否则将出现内存泄漏。ptr=NULL时函数什么都不干。该函数只能用于释放用tpalloc分配的内存。 设置环境变量 VIEWDIR32 VIEW定义文件的目录,多个UNIX用“:”,Windows用”;”分隔 VIEWFILES32 VIEW定义文件名,多个用“,”分隔。 建立VIEW定义文件 Type 类型 short, long, float,double, char, string, carray.
15、 Cname 字段名 Fbname FML字段名,当存在VIEW与FML相互转换时设置 Count 字段出现的个数,数组 flag 标志。一般不用 Size 大小,只在类型为string和carray时使用 Null 指示空值。缺省时,数字类型为(0/0.0),字符为0字符,字符串为空串。示例: #type cname fbname count flag size null float amount - 1 - - 0.0 编译VIEW定义文件viewc32 -n -d viewdir viewfile-n 使用的是非FML关联的VIEW-d 生成的.h文件与.V视图文件目录,缺省为当前目录
16、使用VIEW按一般的C结构使用即可,使用时包含viewc32生成的头文件。 下面演示VIEW的使用 Client.cpp 使用VIEW的客户端 Server.cpp 使用VIEW的服务端 VIEW的特点:效率高,结构固定不可变 FML(Field Manipulation Language)是管理字段的C语言函数。相对于固定的VIEW,它的数据组织是可变的。它有FML头信息、索引和字段数据。不用了解其内部实现,只需调用操作它的FML函数即可。 常用函数在fml32.h中定义,FML有很多函数,常用的有10个左右 设置环境变量 FLDTBLDIR32 FML字段表文件目录 FIELDTBLS32
17、 FML字段表文件 定义字段表文件(Field Table File) *base value 字段的起始编号。1-100,6000-7000表系统保留 Name 字段名 Number 编号 type 类型 与VIEW相同,多了view32, fml32类型 flags 不用设置 Comments 注释 FML定义文件例子*base 100# name number type flags commentsSUM 10 float - -AMT 11 double - - 生成头文件(用于使用FML函数)mkfldhdr32 field_table_file头文件是字段名宏,例如:#define
18、 SUM (FIELDID32)167772312 /*number 110 type float */头文件生成之后,我们就可以使用FML函数了。 增加FML字段int Fadd32(FBFR32* fbfr,/* 缓冲区地址 */FLDID32 fieldid,/* 字段号,见用mkfldhdr生成的头文件 */char* value,/* 字段值 */FLDLEN32 len);/* 数组时设置,数组长度,非数组设为0*/返回值:失败返回-1 更改FML字段值int Fchg32(FBFR32* fbfr,/* 缓冲区地址 */FLDID32 fieldid,/* 字段号 */FLDOC
19、C32 occ,/* 相同字段出现的次数,-1作用同Fadd */char* value,/* 字段值 */FLDLEN32 len);/* 数组长度 */返回值:失败返回-1 得到字段值int Fget32(FBFR32* fbfr,/* 缓冲区地址 */FLDID32 fieldid,/* 字段号 */int occ,/* 出现次数,首次出现为 0 */char* value,/* 保存取出的值的缓冲区 */FLDLEN32 *maxlen);/* 实现取出的字节数 */ 得到字段出现的次数int Foccur32(FBFR32* fbfr,/* 缓冲区地址 */FLDID32 field
20、id);/* 字段号 */ 打印所有字段int Fprint32(FBFR32* fbfr);/* 缓冲区地址 */ 删除字段int Fdelete32(FBFR32* fbfr,/* 缓冲区地址 */FLDID32 fieldid)/* 字段号 */ 返回缓冲区的大小int Fsizeof(FBFR32* fbfr)/* 缓冲区地址 */ 同时利用FML与VIEW的优点FML扩展性好,传输效率高,但不如VIEW使用方便。 在VIEW定义文件中建立与FML的映射设置FBName为对应的FML字段名 使用转换函数int Fvstof32(FBFR32* fbfr, char* struct_bu
21、f, int mode, char* view_name);参数mode 操作模式 FJOIN, FOJOIN, FCONCAT, FUPDATEint Fvftos32(FBFR32* fbfr,char* struct_buf, char* view_name); FML的字段可以是FML或VIEW这一功能非常有用,可以用FML表示非常复杂的对象。 提取字符编码int tpgetmbenc(char* buf, char* enc_name, long flags); 设置字符编码int tpsetmbenc(char* buf, char* enc_name, long flags);
22、设置环境变量TPMBENCint tuxsetmbenc(char* enc_name, long flags); 读取环境变量TPMBENCint tuxgetmbenc(char* enc_name, long flags); 进行编码转换int tpconvmb(char* buf, int* len, char* target_enc, long flags); 加入到应用系统 退出应用系统 编译和创建Tuxedo客户(分Native/WSC) 例子演示 函数int tpinit (TPINIT *tpinfo); /* TPINIT结构,不使用附加特性,设为NULL*/TPINIT
23、名为TPINIT的类型缓冲区,成员字段如下: char usrnameMAXTIDENT+2; /* 用户名 */char cltnameMAXTIDENT+2; /* 客户名 */char passwdMAXTIDENT+2; /* 口令 */char grpnameMAXTIDENT+2; /* 组名 */long flags;/* 标志位, 消息通知的上下文模式 */long datalen;/* data的长度 */long data;/* 应用数据,此为占位符,长度可变 */ 检查是否要求授权(是否要设置tpinit) int tpchkauth(void) 返回值:TPNOAUTH
24、 不要求授权TPSYSAUTH 系统级授权TPAPPAUTH 系统级和应用级授权 函数int tpterm(void)返回值:失败返回-1说明:tpterm调用多次后,除第一次外,以后的调用什么都做。buildclient -w -o filename -f filenames -l filenames-w 编译工作站客户-f 要编译的文件名或编译参数,目标文件先于tuxedo库进行连接-l 类同-f,目标文件在tuxedo库之后进连接 看文件simpcl.c 编译 运行 main函数哪里去了? 系统支持的调用函数 服务例程编写原则 定义一个服务 终止服务处理 构建服务器程序C/C+的程序都有
25、一个main函数,是程序的执行入口。Tuxedo隐含生成main函数,主函数内部插入有非常关键的代码。主函数的代码段类似如下:int main(int argc, char* argv) /* 屏蔽能HANG的信号,设置SIGTERM连结BB, 建立队列,发布服务 */if (tpsvrinit(usr_argc, usr_argv) = -1)return -1;while(1) msg = rcv_msg();dispatch(msg);tpsrvdone();return 0; 原型:int tpsvrinit(int argc,/* 参数个数 */char* argv);/* 参数值的
26、数组 */返回值:如果返回-1服务器将不能启动。说明:参数是指-之后的应用程序(不是服务参数)argv0是否为程序名?文档中没有说明,做一个实例测试。服务函数一般用来初始化程序,如连结数据库,打开日志文件,设置运行环境、创建服务对象等。 原型:void tpsvrdone(void);说明:应该是tpsvrinit()反向操作。前者分配资源,后者释放资源。 服务请求返回必须以tpreturn或tpforward的方式结束。即使是响应tpacall_no_reply,也要调用tpreturn(TPSUCCESS, 0, 0, 0, 0); 服务请求返回当以tpacall(指示回复)调用其它服务时
27、,必须得到所有回复后,才能调用tpreturn/tpforward,或以tpcancel()放弃接收异步调用的回复。 一次只处理一个请求 例程在tpreturn/tpforward返回之前,没有机会再处理其它请求。 服务函数原型:void service(TPSVCINFO* rqst)TPSVINFO表示服务请求信息,字段如下:char name32;/* 服务名称 */long flags;/* 标志位,与前端调用有关,TPTRAN-在事务中 */char *data;/* 请求缓冲区 */long len;/* 长度 */int cd;/* 会话描述符,会话服务器有效 */int app
28、key;/* 应用键值,缺省为-1,用于应用定义授权机制 */CLIENTID cltid; /* 客户机标识号 */void ABAL(TPSVCINFO *transb) struct aud *transv; /* view of decoded message */transv = (struct aud *)transb-data;EXEC SQL declare acur cursor forselect SUM(BALANCE) from ACCOUNT;EXEC SQL open acur;EXEC SQL fetch acur into :bal; if (SQLCODE !
29、= SQL_OK) /* nothing found */strcpy (transv-ermsg,abal failed in sql aggregation);EXEC SQL close acur;tpreturn(TPFAIL, 0, transb-data, sizeof(struct aud), 0);EXEC SQL close acur;transv-balance = bal;tpreturn (TPSUCCESS, 0, transb-data, sizeof(struct aud), 0); 结束一个服务处理有三种方式 调用tpreturn返回响应 调用tpforward
30、将处理交给下一个服务 调用tpcancel放弃服务处理 函数:void tpreturn(int rval,/* 返回值 */int rcode,/* 返回代码 */char *data,/* 返回数据 */long len,/* 数据长度,只在XML/CARRAY时设置*/long flags);/* 标志位 */返回值:为应用级设置。TPSUCCESS,TPFAIL,TPEXIT返回代码:用户可以通过全局变量得到tpurcode标志位:目前未使用。Tuxedo很多函数的末尾参数都是标志位,用于控制函数的行为。当接收超时时,要调用tpcancel撤销回复链路int cd1 =tpacall(
31、sname, (char*)audv, sizeof(struct aud),TPNOTRAN);if (cd1 = -1) if (tpgetrply(cd1, (char*)&audv,&audrl, 0) = -1) if (tperrno = TPETIME) tpcancel(cd1);tpreturn(TPSUCCESS, 0,NULL, 0L, 0);当一个请求还需要被其它服务处理时,可以转发请求。函数:void tpforward(char *svc,/* 要转发到的服务 */char *data,/* 请求缓冲区 */ long len,/* 数据长度 =0
32、表示空长 */long flags)/* 标志,目前未使用,设置为0 */说明:执行tpforward后,将产生longjmp调用,其后的代码不会再执行,服务进程回到起点,准备处理下一个请求。longjump与C+的析构机制不符,不要在对象内部执行fpforward,否则后果不可预知。 函数:int tpadvertise(char *svc,/* 要发布的服务名,不能为NULL */void *func)/* 服务函数指针,不能为NULL */int tpunadvertise(char *svc);/* 要取消发布的服务名,不能为NULL */注:服务名的长度为15个buildserver
33、 -o filename -f filenames -l filenames -s v -t rrm-o 输出的程序文件名-f 输入的文件,目标代码在Tuxedo库之前链结-l 输入的文件,目标代码在Tuxedo库之后链结-s 要发布的服务,多个服务使用多个-s-t 生成线程安全代码-r 程序要访问的rm类型名 (名称在RM文件中,该文件指示了使用XA要链入的库文件)-v 输出编译细节(verbose)到标准输出例:buildserver o ACCT f acct.o s NEW_ACCT:OPEN_ACCT s CLOSE_ACCT交易系统的绝大部分交易采用该模型,少量采用会话模型(如批量
34、和循环报文)使用最频繁的几个函数:tpreturn 返回响应(只用在服务例程上)tpcall 同步调用tpacall异步调用(包括期望接收回复和不接收二种)tpforward 转发请求(只用在服务例程上)tpgetrply 得到tpacall的回复int tpcall(char *svc,/* 要调用的服务名 */char *idata,/* 输入缓冲区指针(请求),不能为NULL */long ilen,/* 输入长度,自描述缓冲区可不设 */char *odata,/* 输出缓冲区指针的地址,不能为NULL */long *olen,/* 输出大小,不能为NULL */long flags
35、)/* 标志位 */返回值: 为-1为调用失败标志位:TPNOTRAN 服务不参与全局事TPNOCHANGE 输出缓冲区的类型不可更改TPNOBLOCK 非阻塞调用 int tpacall(char *svc,/* 要调用的服务名,不能为NULL */char *data, /* 请求缓冲区,不能为NULL */long len, /* 数据和长度 */long flags)/* 标志位* /返回值:-1为失败,成功返回会话描述符,该描述符由tpgetrply使用。标志位:与tpcall相同的部分TPNOREPLY 不期望接收回复,该参数非常重要,高性能的服务器往往使用该标志进行请求推送。in
36、t tpgetrply(int *cd,/* 由tpacall返回的描述符 */char *data,/* 响应数据缓冲区指针的地址 */long *len,/* 接收到的响应长度 */long flags);/* 标志位 */返回值:出错返回-1标志位:类同tpcall(无TPNOTRAN)的部分TPGETANY 不考虑cd,获取所有回复给调用者消息/* 由tpacall实现的tpcall */int my_tpcall(char* svc, char* idata, long ilen, char* odata, long* olen, long flags) int cd = tpaca
37、ll(svc, idata, ilen, flags);return (cd = -1)?-1:tpgetrply(&cd, odata, olen, flags);说明:调用者使用要求回复的tpacall是为了在请求与响应到达之间的时间段里可以做点别的工作。Void SVC(TPSVCINOF* rqst)char* rbuf = (char*)tpalloc(STRING, 0, 0);if (tpacall(PRINTER, rbuf, rlen, TPNOTRAN|TPNOREPLY)= -1)tpfree(rbuf);tpreturn(TPFAIL, 0, 0, 0, 0);
38、tpfree(rbuf);tpreturn(TPSUCCESS, 0, 0, 0, 0);int tpsprio(int prio, /* 优先级0.100,如flags是指相对值,此处设置为0 */long flags); /* 标志 TPABSOLUTE 采用绝对值,这时prio也给个值 */返回值:失败返回-1说明:此函数是对当前请求有影响。可将一些要求尽可以快速响应的交易设置为高的优先级,下面的例子为“取款”交易的优先级提高一级。if (tpsprio(PRIORITY, 0L) = -1) tpreturn(TPFAIL, 0,transb-data, 0L, 0);else if (tpcall(WITHDRAWAL, (char*)reqfb,0, (char*)&reqfb, (long *)&reqlen,TPSIGRSTRT) = -1) tpreturn(TPFAIL, 0,transb-data, 0L, 0); 会话通讯的特点 会话建立、应用与终止 建立会话服务程序 会话通讯事件 有状态的会话建立后,服务进程就只为建立该会话的请求者使用,交互状态一直有效 服务进程共享度低不适用大量的前端用户使用,特别是有人参与会话。如果能用请求/响应实现,就不
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 返程投资项目可行性分析协议
- 投资回报2026年股权合同
- 2026年大学生士兵典型人物事迹启示
- 2026年医院冰蓄冷空调系统移峰填谷
- 棋道馆2026年学员积分兑换协议
- 2025年工业物联网数据分析
- 2026年大班语言领域学期教学计划
- 2026年中国建筑企业海外工程分包法律风险防范
- 2026年芯片设计行业现状与工程师成长路径
- 2026年幼儿园茶文化启蒙教育的实践路径
- 戏剧与美育智慧树知到期末考试答案章节答案2024年长江人民艺术剧院
- 输液泵的使用培训课件
- 【复习资料】10398现代汉语语法修辞研究(练习测试题库及答案)
- 第五章-立地条件划分
- 说专业-物流管理专业
- 高三历史一轮复习研讨会经验交流课件
- 抖音小店出售协议书
- 广东深圳红岭中学物理自主招生试卷
- (完整word)幼小衔接拼音试卷十套打印版981
- 中国传统故事英文哪吒闹海二篇
- 西方经济学宏观第十四章
评论
0/150
提交评论