系统自带authsvr服务进程,和两个子例程,tpsvrinit(),tpsvrdone。
authsvr:客户端调用tpinit进行认证时,由交易TPAPPAUTH回应。
服务端自动调用tpsvrinit,可以在函数中进行数据库连接和处理命令行参数。
结束时tpsvrdone也被自动调用,可以在函数中断开数据库连接。
这两个例程分别在进程开始时和进程将要结束时,被自动调用。
服务端编程指导:
交易内一次只能接收一个请求,发送一个响应。
交易必须以tpretrurn, tpforward结束。
或交易内使用了tpacall,在返回或转发前,要么等待回应,要么使用tpcancel。
tpreturn一旦被调用,控制权就转移到main函数,未进行显示收取的响应会被丢弃,此时客户端会收到错误。
客户端调用tpcall后,若服务端此时对应的tpreturn成功返回,客户端tpcall才能返回。
客户端调用tpacall后,若服务端此时对应的tpreturn成功返回,客户端tpgetrply才能返回。 返回的数据,可由客户端从指针*data处取得。
tpforward调用时,程序逻辑应保证之前的处理都正确,响应被收到。被调用后,交易不再等待响应。main函数取得控制权。被请求的另一个交易负责响应原来的请求。不能将请求转发到自身。
tpreturn 的参数:
rval: 表明交易是否成功执行。
rcode: 是应用自定义的返回值。客户端可通过tpurcode获得tpreturn的rcode值,而不论交易是否成功。
data: 该缓冲区由客户端传递,服务端可以将回应数据写至此地址。也可以进行tprealloc.而不能tpfree. 服务端也可以自行tpalloc一个缓冲区,并返回给缓冲区,但需要自行若管理。如果发送的数据长度大于已分配的,tuxedo会自动扩大缓冲。
len: 用来指示响应缓冲的长。客户端可据此得知数据是否有变化。
如果客户端需要收到一个响应,而tpreturn自身处理时出错,这时tpcall或tpgetrply会失败,客户端应检查tperrno. 此时客户端的data缓冲区没有变化。若交易返回的消息不符客户端要求,则无法判断应用状态,此时原来的缓冲区保持不变。如果交易超时,响应数据不会被发送。
发布与取消交易名:
当一个服务进程被启动后,它会根据配置文件来向公告板上广告自己有交易名。这通常由buildserver命令执行时完成。
tpcall:
客户端收到响应后。总是应该使用返回参数中的地址,并比较缓冲区是否有变化。
tpacall:
返回值为一个描述符,供tpreply使用。若标志位包含了tpnoreply,返回的描述符为无符值,不能被随后的tpgetrply引用。即使在事务模式下,响应可能未全部到达,但仍允许客户端提交,为保证不出错,要尽量保证所有的响应能到达。
在一个事务中,可以为tpcall,tpacall都指定 TPNOREPLY,TPNOTRAN标志。
关于缓冲区的参数,type,subtype都要和服务端所期望的类型完全相同。否则系统会出错。
tpacall的缓冲区只要在返回后,就立即可用作下一次发送请求。
tpgetrply的len指针不能为空。此函数会一直阻塞直到收到响应。
tpsprio只用作用于接下来的一个请求,无论是同步,异步,被转发的。其默认值为对应交易的值。
基于对话的开发:
对话服务进程不允许使用请求转发。
同一个服务端/客户端都可以同时进行多个会话,最大值为64
建立连接的时候,可同时进行数据的发送。
会话内依然可以使用tpcall,tpacall呼叫其它的交易。
建议在服务端使用tpreturn结束连接。遭遇异常时,可由客户端使用tpdiscon来断开连接。
对 话开始时由tpconnect 建立的连接是一个半双工的虚连接: 只有获得当前连接控制权的一方才能使用tpsend发送数据 。通过由控制方指定标志值可将连接的控制权转移至连接的另一端。 如果客户端tpconnect时指定了TPSENDONLY则表明客户端取得控制权,若为TPRECVONLY表明服务端取得控制权。tpsend可指定 标志值 ,而tprecv可获得事件值 。
对于具有层级的会话(嵌套会话),为了使多个会话能有序地断开连接,一般由被调用的最深层次的服务端调用tpreturn来终止连接。
基于全局事务的开发:
可以跨越多个服务器上的多个资源管理器,并将提交给它们的多个事务共同作为一个大的逻辑事务,要么全部提交,要么全部回滚。如果某个事务内调用了带有 TPNOTRAN标志值的tpcall,tpacall,tpconnect,则它们执行的成功与否不被事务管理器所参考用来提交与回滚但事务依然会因此 某个呼叫等待而超时。
事务内可以使用会话。已经开始的事务内不可以再调用tpbegin().
tpbegin:
timeout参数应该参考tuxconfig中SCANUNIT(默认为10s)的值,与实际应用关系较大,若和用户交互等待时间较短,处于生产环境时此时间较长。flags目前必须置0. SCANUNI值指示系统扫描阻塞的交易调用或超时事务的周期。
tpsuspend,tpresume:
事务可以被暂停与继续,除了当前还有未处理的异步事件时。另一个进程可以根据事务标识符来恢复事务。
tpcommit:
必须由调用tpbegin的进程来调用tpcommit,tpabort.否则无效。 在未收到响应时,不应使用tpcommit. 当之前的调用失败时,tpcommit不应被使用。
两步提交:
主管理器向所有从管理器发送提交指示,所有从设备回送准备完成时,才最终提交所有事务。tpcommit可以在一步提交时返回,也可以在两步提交后返回。
tpabort:
用来结束一个事务,之前未收到响应的所有呼叫描述符都会不可用,而且事务之前所做的改变都会被回滚。
可以在服务端设置AUTORUN为Y,使得一个事务可以自动开始。这样在收到一个带有tpnotran的tpcall时,不会有意料之外的情况。 关于客户端与服务端是否共同支持事务的讨论比较多。
关于tuxedo队列的开发:
tuxedo队列支持出队,入队,转发等操作,并且负责管理基于事务的队列。
使用tuxedo队列,管理员需要做如下任务:
定义一个组,专用于队列,比如TMS_QM。
服务进程TMQUEUE,TMQFORWARD,需要被定义。
队列空间需要被创建。
事务中使用队列:
系统允许我们在同一个事务中先出队响应,再入队请求。但不允许先入队请求,再出队响应。在同一个事务中用于入队的请求需要及时成功提交(若入队后,事务回滚,则某些tpcall可能会重做多次),即使响应当前还未到达。
若出队操作失败,并且当前事务回滚,可以通过配置重试次数与重试间隔来再次dequque.
关于出错处理:
tperrno :
所有的atmi函数如果返回值不正常,系统都会设置tperrno. 对于tpreturn,tpforward,它们用来结束一个交易,服务端通过返回值即可判断出错。客户端只能通过检查tpcall返回值后,再tperrno来检查是否出错原因。
tpurcode:
通过tpreturn的rcode用来设置tpurcode值,该值用来表示应用自定义的一些状态,与tpreturn的返回值是否正常无关。
tuxedo系统错误:
当发现系统级错误时,tuxedo会向事务日志中心发送一条日志消息,并设置tperrno.
呼叫描述符错误:
在异步呼叫时,请求端与响应端通过呼叫描述符来关联匹配。会话型呼叫时,虚拟连接通过呼叫描述符来标识。
描述符的数量若超出资源限制,则出错。一个应用的同一个上下文中只允许有50个未响应的消息在排队。
描述符若无效,则不能使用。如事务结束或超时后,描述符不可以再被使用。
对话错误:
如果一个描述符不可用,tpsend,tprecv,tpdiscon返回错误。在对话连接建立后,若有事件发生,tpsend会发送失败,并且revent值会被设置。
重复对象错误:
交易名不可被重复声明,事务不可被多次恢复,事件不可被多次订阅。
通信错误tpesvcfail,tpesvcerr:
如果tpreturn在处理过程中发生错误,返回错误并设置tperrno为tpesvcerr,数据不被发送。对端通过tperrno来获知错误。
如果通过用户编码返回rval为tpfail则系统将tperrno设为tpesvcfail,表示这属于应用自定义的异常,并将数据发送至对端。
通信错误tpeblock,tpgotsig
如果tpcall指定TPNOBLICK而发送数据过程中被阻塞,则返回TPEBLOCK。此标志值指定发送数据过程而不限定立即得到响应。
如果函数处理过程被信号中断,则返回tpgotsig.可通过在标志值tpsigrstrt来保证函数自动重启不致失败。
参数不合法:
应用级别的错误,tuxedo系统可以自动检测,建议在应用级别检查所传参数合法。
无效条目:
通常在分配资源类函数中,若系统在资源范围内找不到对应的类型标识会返回。
tpalloc中指定了无效的缓冲类型。
tpinit无法在公告板中为自身创建条目,此时公告板空间可能不够。
tpcall请求的交易还未在公告板注册。
tpconnect请求的服务名不存在。或该服务类型不是对话类型的。
togprio中指定的请求并不存在。
tpunadvertise中指定的订阅名不存在。
tpenqueue/dequque,指定的队列不可用。
tppost/subscribe系统事件分发器不可访问。
操作系统错误:
如果tperrno 返回TPEOS,则表明某个系统调用失败。此时可以使用Uunixerr来获得对应的系统errno.
权限错误:
若tpinit失败,同时tperrno被置为TPEPERM,则表明配置文件有问
。
错误(TPEPROTO):
主要由函数调用的顺序不当或函数在不恰当的进程内被调用未加入应用就调用tpcall。未进行tpbegin.却调用tpcommit.
队列错误(TPEDIAGNOSTIC):
错误原因可由ctl缓冲取得。
资源管理器错误(TPERMERR):
tpopen,tpclose发生错误,错误原因需要对数据库相关信息进行判断。
超时错误:
在配置文件中可以定义两种时间限制。一个应用等待响应的时间,称为阻塞时间。一个事务处理的时间,称为事务超时。
在事务模式下,若系统返回TPETIME表明一个事务超时。事务处理时,事务超时的作用会覆盖掉阻塞超时。
普通模式下,若一个异步呼叫超时,调用会失败,但呼叫标识符仍可用。
若发生了事务超时,则其中进行的异步呼叫对应的呼叫标识符不再可用。
缓冲区类型错误:
函数发现不识别的缓冲区类型。
事务专题:
在事务模式下,需要遵循如下建议,
隶属于同个事务的所有进程,如果发送了请求则要等待响应。除了在tpacall中指定tpnotran,tpnoreply.
服务端在返回或转发前一定要等待所有的请求收到响应。
发起tpbegin的一端在未收到响应前,不可以调用tpcommit.
如果事务并未超时但被标识为abort-only,接下来的交互都应标志TPNOTRAN,以保证整个事务能够被正确的回滚。
若事务被标识为abort-only,则tpgetrply返回值仅仅反映本地状态。
一旦tpgetrply, tpsend,tprecv发生错误,则对应的标识符失效,不论是否事务模式。
一旦事务被终止,所有的未决呼叫标签符无效 。
事务相关的错误:
只有在当前的客户端与资源管理器处理完毕,才可以对之前暂停的全局事务进行恢复。
对于不支持事务的服务端,发出的请求应带上TPNOTRAN标志。
被 置abor-only的情况,tpreturn返回时处理参数出现错误,rval参数被置为TPFAIL。在此情况下应该使用tpabort进行终止,所 做更改会被回滚,其后所有的描述符将不可用。但只要事务还没有超时,依然可以使用带有TPNOTRAN标志的函数进行操作。
一旦事务超时,能发送请求的类型只有异步通信,并置TPNOREPLY,TPNOBLOCK,TPNOTRAN标志。
如果 在tpcommit时发生超时,需要查看错误码或资源管理器。
tpterm用来将客户端的上下文从应用中移除。如果此时还处于事务模式,则出错,客户端的资源未被改动。
不需要程序员显式对数据库者提交操作。tuxedo会自动对资源管理器进行提交与终止 。
在事务模式下参与方又进行了另一个呼叫:
若服务端发生严重错误,则当前事务被置为abort-only.若参与方被中断,则当前事务也会失败。另一个呼叫的类型不得为TPNOREPLY.