函数名 |
输入FML字段 |
输出 FML字段 |
服务名称 |
BALANCE() |
ACCOUNT_ID |
SBALANCE |
INQUIRY |
WITHDRAWAL() |
ACCOUNT_ID SAMOUNT |
SBALANCE |
WITHDRAWAL |
DEPOSIT() |
ACCOUNT_ID SAMOUNT |
SBALANCE |
DEPOSIT |
TRANSFER() |
ACCOUNT_ID (0) ACCOUNT_ID (1) SAMOUNT |
SBALANCE (0) SBALANCE (1) |
TRANSFER |
OPEN_ACCT() |
LAST_NAME FIRST_NAME MID_INIT SSN ADDRESS PHONE ACCT_TYPE BRANCH_ID SAMOUNT |
ACCOUNT_ID SBALANCE |
OPEN_ACCT |
CLOSE_ACCT() |
ACCOUNT_ID |
SBALANCE |
CLOSE_ACCT |
⑷. 调用成功完成后,每个函数可以从返回的FML缓冲区中取得需要的数据
do_tpcall()函数的代码如下:
static int do_tpcall(char *service){
long len;
char *server_status;
/* 开始一个全局事务 */
if (tpbegin(30, 0) == -1) {
(void)fprintf(stderr, “ERROR: tpbegin failed (%s)\n”,tpstrerror(tperrno));
return(-1);
}
/* 使用用户数据请求服务 */
if (tpcall(service, (char *)fbfr, 0, (char **)&fbfr, &len,0) == -1) {
if(tperrno== TPESVCFAIL && fbfr != NULL &&
(server_status=Ffind(fbfr,STATLIN,0,0)) != 0) {
(void)fprintf(stderr, “%s returns failure (%s)\n”, service,server_status);
}else {
(void)fprintf(stderr,”ERROR: %s failed (%s)\n”, service,
tpstrerror(tperrno));
}
/* 终止事务*/
(void) tpabort(0);
return(-1);
}
/* 提交事务 */
if(tpcommit(0) < 0) {
(void)fprintf(stderr, “ERROR: tpcommit failed (%s)\n”,tpstrerror(tperrno));
return(-1);
}
return(0);
}
2.bankapp中怎样使用ud(1)
bankapp使用到了Tuxedo系统的ud(1)程序,它允许数据从标准输入读取,并送到服务。populate和driver例程都用到了ud。
在populate中,一个叫gendata的程序把服务请求以及要输入数据库的客户帐号信息一起传给了ud。
在driver中也存在类似的数据流,但程序是gentran,它的作用是把事务传递给应用程序以模拟一个活动系统。
3.一个请求/响应客户:audio.c
audit中一个请求/响应客户程序,用于支行或全行范围内的余额查询,它用到ABAL、TBAL、ABAL_BID、TBAL_BID服务,你可以通过如下两种方法来激活它:
audit [-a|-t],-a打印全行所有账号总额,[-t]打印全行范围内所有出纳员的现金供应。
audit [-a|-t] branch_ID,打印某支行Branch_ID的上述信息。
audit源代码包括两个主要部分:main()和sum_bal()子程序。两部分都用到了ATMI函数,它用到了一个在aud.h头文件中定义的VIEW类型的缓冲区,如下它的伪码:
main(){
Parse command-line options with getopt();
Join application with tpinit();
Begin global transaction with tpbegin();
If (branch_ID specified) {
Allocate buffer for service requests with tpalloc();
Place branch_ID into the aud structure;
Do tpcall() to “ABAL_BID” or “TBAL_BID”;
Print balance for branch_ID;
Free buffer with tpfree();
}else
call subroutine sum_bal();
Commit global transaction with tpcommit();
Leave application with tpterm();
}
sum_bal(){
Allocate buffer for service requests with tpalloc();
For (each of several representative branch_ID’s,one for each site)
Do tpacall() to “ABAL” or “TBAL”;
For (each representative branch_ID) {
Do tpgetrply() wtith TPGETANY flag set
to retrieve replies;
Add balance to total;
Print total balance;
}
Free buffer with tpfree();
}
audit.c首先检查命令行参数,看是否指定的支行代号。若指定,则将它放入aud结构,并调用ABAL_BID或TBAL_BID服务来处理请求;否则就调用sum_bal()子过程来处理。它们的程序流程图如下:
4.一个会话客户:auditcon.c
auditcon是audit的会话版,它使用了ATMI与会话相关的函数,如使用tpconnect()建立服务与客户之间的连接,用tpsend()发送一条消息,用tprecv()接收消息。如下是它的伪码:
main(){
Join the application
Begin a transaction
Open a connection to conversational service AUDITC
Do until (user says to quit) {
Query user for input
Send service request
Receive response
Print response on user’s terminal
Prompt for further input
}
Commit transaction
Leave the application
}
5.一个监视事件的客户bankmgr.c
bankmgr是一个始终运行的应用程序,它订阅应用程序定义的事件,如一次存取超过10000美元的事件。
§3.3 检查bankapp的服务器和服务
服务器是一些可执行的进程,它们提供一个或多个服务。在Tuxedo系统中,服务器始终接受来自客户端的服务请求,并将它们分配给某些服务,让它们来处理请求。所有bankapp的服务都是用C语言写的,包含有嵌入式SQL语句的C程序扩展名不是C而是EC。TRANSFER由XFER服务器来提供,它是唯一一个不包含嵌入式SQL的服务。所有bankapp服务使用ATMI的函数来管理类型缓冲区、和其它服务进行同步或异不通信、定义全局事务、一般地访问资源服务器、把响应发送回客户端。
1.bankapp的请求/响应服务器
bankapp的5个服务器中,有4个用到了嵌入式SQL访问资源管理器,这些服务器的扩展名为EC。XFER是一个转账的服务器,本身不调用资源管理器,而调用了其它服务器中的WITHDRAWAL和DEPOSIT两个服务。5个服务器的描述如下:
服务器 |
提供的功能 |
BTADD.EC |
允许任何一个站的支行和出纳员的记录添加到数据库中 |
ACCT.EC |
提供一些账号相关的有代表性的服务,如OPEN_ACCT, CLOSE_ACCT |
TLR.EC |
为出纳员提供服务,如WITHDRAWAL, DEPOSIT, INQUIRY,每一个TLR进程标识着它本身是TELLER文件中的一个真实的出纳员 |
XFER.C |
在账号之间进行转账业务 |
BAL.EC |
计算所有支行或某个支行的余额 |
2.bankapp的会话服务器
AUDITC是一个会话服务器的例子,它提供了一个服务,名字也叫AUDITC。客户机auditcon建立一个与服务AUDITC的会话连接,然后发出请求。AUDITC分析请求,并调用适当的服务(ABAL,TBAL,ABAL_BID,TBAL_BID),当AUDITC从这些服务获得响应后,再将它们送回auditcon。会话服务器可以以客户机的身份请求其它服务,也可以连接到其它会话服务器。
3.bankapp的服务
bankapp提供了12个请求/响应服务。服务名和C语言函数名相同:
服务名 |
提供服务器 |
输入 |
执行功能 |
BR_ADD |
BTADD |
FML缓冲区 |
添加一个新支行记录 |
TLR_ADD |
BTADD |
FML缓冲区 |
添加一条新出纳员记录 |
OPEN_ACCT |
ACCT |
FML缓冲区 |
向ACCOUNT文件中插入一条记录并调用DEPOSIT存入开户金额;在支行代号BRANCH_ID的基础上选择一个ACCOUNT_ID |
CLOSE_ACCT |
ACCT |
FML缓冲区 |
删除一个ACCOUNT记录;验证ACCOUNT_ID; 调用WITHDRAWAL取走所有余额 |
WITHDRAWAL |
TLR |
FML缓冲区 |
从一个指定的支行、出纳员、账号取款; 验证ACCOUNT_ID和SAMOUNT字段 |
DEPOSIT |
TLR |
FML缓冲区 |
向某个支行、出纳员、账号存款; 验证ACCOUNT_ID和SAMOUNT字段 |
INQUIRY |
TLR |
FML缓冲区 |
查询账号余额;验证ACCOUNT_ID |
TRANSFER |
XFER |
FML缓冲区 |
执行一个tpcall()调用,先后请求WITHDRAWAL和DEPOSIT服务 |
ABAL |
BAL |
aud.v的VIEW缓冲区 |
计算某一个站点所有账号的余额 |
TBAL |
BAL |
aud.v的VIEW缓冲区 |
计算某个站点所有支行出纳员的余额 |
ABAL_BID |
BAL |
aud.v的VIEW缓冲区 |
计算BRANCH_ID的账号余额 |
以下文章点击率最高
Loading…