分类:
2009-08-26 11:12:37
银行网络通常采用星形拓朴结构,由若干前置机与一台主机相连,每一台前置机又可携带多台终端机。前置机与主机是客户机与服务器的关系,即client与server(C/S)架构。另一方面,银行主机数据库与主机应用程序之间也是server与client的关系。前置机、主机应用程序服务器、主机数据库服务器三者就构成了三层架构,既保证了数据的高效,又能充分保证安全。
主机应用程序与主机数据库之间的通信由数据库管理系统(如informix)控制。前置机应用程序与主机应用程序之间的通信由通讯中间件完成。前置机应用程序与主机应用程序通常由系统集成商开发,通讯中间件则是一个独立的产品,既可由系统集成商提供,也可由第三方提供。详见图7-1。
图7-1 三层架构示意图
CICS/6000为程序员提供了一些在应用程序服务器上的CICS API命令,这些API命令是嵌入到C程序中的CICS编程语句,用以完成CICS所提供的交易功能。CICS API用高级格式编程,每条命令都以EXEC CICS起始,再跟上上些必须的或可选的参数。
每一条CICS命令在执行时都有可能出现错误,如访问并不存在的文件、启动一个无权访问的交易程序或与一个远程没有启动的CICS域通信等。这种情况在CICS中被称为异常条件。在C程序中,缺省动作是终止CICS任务,并返回一个代码说明出错原因。这个返回代码被称为异常中断代码,即ABEND代码。为了使程序能够确定CICS命令的执行情况,每条CICS命令执行后都将返回一个反馈码,这是通过修改EIB(EXEC INTERFACE BLOCK)中的字段实现的,特别是在所有CICS命令中加入RESP选项变量,取得这个返回码。程序根据返回值进行必要的逻辑处理。RESP选项的返回值或EIB中返回值是一个32位整数,为此CICS/6000提供一个宏命令将某一执行条件的字符表达方式转换成相应的数值形式主义,这个宏是DFHRESP(),它以数值型变量为参数,在对CICS程序进行预编译时进行扩展。如果一条CICS命令正确执行,则条件值被设置成NORMAL。例如:
int resp_code;
EXEC CICS LINK PROGRAM(program) RESP(resp_code);
if (resp_code == DFHRESP(NORMAL))
{
……
}
☆ EXEC CICS ABEND
导致CICS交易程序异常中断。语法:
EXEC CICS ABEND [ABCODE (NAME)] [CANCEL]
其中ABCODE参数指定一个四位长字符串,表示中断码。而CANCEL选项可以忽略程序中由命令EXEC CICS HANDLE ABEND中所指定的任何控制。任何由程序或交易所完成的可恢复性工作都被回滚。而ECI或EPI客户编程接口也能接收到中断码,进而进行前端处理。
☆ EXEC CICS RETURN
结束一个CICS程序或将程序控制权返回给发布LINK命令的CICS程序。语法:
EXEC CICS RETURN [TRANSID(name)]
[COMMAREA (data_area)] [LENGTH (data_len)]
这条命令结束一个CICS程序,若这个程序是被另外一个程序通过EXEC CICS LINK命令调用,则将程序控制权交还给调用程序。如果当前程序已经位于最高层,控制权交给CICS,若此时指定了TRANID选项,则定义了后续启动交易,这种情况通常在交互式应用设计时使用。
☆ EXEC CICS SYNCPOINT
对一个CICS交易进行提交或回滚。语法:
EXEC CICS SYNCPOINT [ROLLBACK]
这个命令指示CICS提交或回滚当前交易所做的任何修改。当交易被提交或回滚后继续执行,直到下一个EXEC CICS SYNCPOINT命令或任务结束命令对交易进行提交或回滚。
非CICS应用程序,即不EXEC CICS命令的应用程序,可以使用ECI(External Call Interface外部调用接口)调用CICS/6000应用程序。这个客户程序调用CICS程序的方法类似于EXEC CICS LINK命令,而被调用的CICS程序称为服务器程序。客户程序调用服务器程序时需要一个服务器程序名和可选的通信存储区。通过通信存储区,客户程序将数据传递给服务器程序,还可以通过这个通信存储区接收服务器程序返回的数据。
当CICS应用服务器程序执行完成后,这个程序对可恢复资源的修改可保持在未提交状态。这个程序的LUW(逻辑工作单元)由调用它的ECI参数指定。若ECI调用是扩展方式(即属性ExtendMode设置为on),则ECI调用所确定的LUW并没有被提交,而后的ECI调用可以运行另外的服务器程序、提交这个LUW或回滚这个LUW。若LUW是扩展的,一个记号(Token)或LUW标识符在第一次ECI调用时将被返回,客户程序可以从eci_luw_token参数中得到,而后的ECI调用必须使用这个值以确定相同的LUW。对于一个新的LUW,eci_luw_token参数必须被设置为0。
ECI客户程序向CICS服务器程序传递数据时需要两个参数:存储区指针eci_commarea和这个存储区长度eci_commarea_length。这个存储区的内容被复制到CICS域中,并经过CICS服务器程序计算修改后返回给ECI客户程序。由ECI向CICS服务器程序发送数据的存储区长度要足够长,以保证CICS服务器程序能够返回ECI所要的所有结果数据。这个存储区的长度不能超过32K,通常情况下要小于30K。
☆ CICS_ExternalCall
CICS_ExternalCall调用CICS服务程序,使其在CICS应用服务器(CICSAS)中运行,另外还可以提交一个扩展方式的LUW、回滚一个扩展方式的LUW、扩展一个扩展方式的LUW、检查异步ECI调用的状态。其语法为:
short CICS_ExternalCall (ECI_PARMS *);
其中,ECI_PARMS的定义如下:
typedef struct
{
cics_sshort_t eci_call_type; /* Call_type values: */
/* CICS OS/2 Version 1 ECI call-types. */
#define ECI_SYNC_CALL 0 /* These call-types should not be used */
#define ECI_ASYNC_CALL 1 /* in new applications. */
#define ECI_SYNC_PARALLEL 2 /* */
#define ECI_ASYNC_PARALLEL 3 /* */
/* CICS Client ECI call-types: */
#define ECI_SYNC 516 /* Synchronous call. */
#define ECI_ASYNC 517 /* Async call used with ECI_GET_REPLY. */
#define ECI_ASYNC_NOTIFY_MSG 518 /* Async call, notify by message. */
#define ECI_ASYNC_NOTIFY_SEM 519 /* Async call, notify by semaphore */
#define ECI_GET_REPLY 520 /* Used to get reply to ASYNC call. */
#define ECI_GET_REPLY_WAIT 521 /* As above but wait for reply. */
#define ECI_GET_SPECIFIC_REPLY 528 /* Get specific ASYNC reply. */
#define ECI_GET_SPECIFIC_REPLY_WAIT 529 /* As above but wait for reply.*/
#define ECI_STATE_SYNC 522 /* Synchronous request for CICS status.*/
#define ECI_STATE_ASYNC 523 /* As above but async, no notify. */
#define ECI_STATE_ASYNC_SEM 524 /* As above but notify by semaphore. */
#define ECI_STATE_ASYNC_MSG 525 /* As above but notify by message. */
cics_char_t eci_program_name[8];/* */
cics_char_t eci_userid[8]; /* */
cics_char_t eci_password[8]; /* */
cics_char_t eci_transid[4]; /* */
cics_char_t eci_abend_code[4]; /* Returned to the caller. */
cics_ptr_t eci_commarea; /* Ptr to commarea or NULL. */
cics_sshort_t eci_commarea_length;/* Should be 0 if above ptr is NULL. */
cics_sshort_t eci_timeout; /* In seconds. */
cics_sshort_t eci_sys_return_code;/* Extra error code if problems arise. */
cics_sshort_t eci_extend_mode; /* Valid values defined below. */
#define ECI_NO_EXTEND 0 /* These values are to be used with */
#define ECI_EXTENDED 1 /* call_types other that ECI_GET_xxx & */
#define ECI_COMMIT 2 /* ECI_STATE_xxx. */
#define ECI_CANCEL ECI_COMMIT
#define ECI_BACKOUT 3 /* */
#define ECI_STATE_IMMEDIATE 4 /* All ECI_STATE_xxx call-types. */
#define ECI_STATE_CHANGED 5 /* ECI_STATE_ASYNC_SEM & */
#define ECI_STATE_CANCEL 6 /* ECI_STATE_ASYNC_MSG call_types only.*/
union /* Fields for async notification. */
{ /* OS/2 specific fields: */
cics_lhandle_t window_handle; /* OS/2 Window for notification. */
cics_lhandle_t sem_handle; /* OS/2 Semaphore for notification. */
struct
{ /* Microsoft Windows specific fields. */
cics_shandle_t hwnd; /* Window handle for notification. */
cics_shandle_t hinstance; /* Program instance handle. */
} win_fields;
} eci_async_notify;
#define eci_sync_wait eci_async_notify.win_fields
cics_ushort_t eci_message_id; /* User-defined message identifier */
cics_sshort_t eci_message_qualifier;/* This value returned on NOTIFY_MSG */
cics_slong_t eci_luw_token; /* Must be set to zero for a new LUW */
cics_char_t eci_sysid[4]; /* Optional CICS sysid */
cics_sshort_t eci_version; /* ECI version identifier: */
#define ECI_VERSION_0 0 /* Fields below not present */
#define ECI_VERSION_1 1 /* Fields to eci_password2 present */
#define ECI_VERSION_
#define ECI_VERSION_MAX 2 /* Maximum value of version */
cics_char_t eci_system_name[8]; /* System to execute ECI call */
CICS_EciNotify_t eci_callback; /* Call back notification function */
cics_char_t eci_userid2[16]; /* Extended userid */
cics_char_t eci_password2[16]; /* Extended password */
cics_char_t eci_tpn[4];
} ECI_PARMS;
CICS/6000提供一系列命令,在CICS/6000域内对资源定义进行加入、删除和修改。
☆ cicsadd
将某一资源加入到CICS/6000的永久库或有条件的加入正在运行的CICS/6000域中的运行库中。
☆ cicsdelete
将某一资源从永久库、运行库或同时从两个库中删除。
☆ cicsupdate
修改永久库中的资源,并加入到运行库中。不能对正在运行的资源进行修改,这个资源必须首先删除,然后再加入。
例如,完成一个CICS的server端例程的编码、编译和链接后,必须将生成的可执行文件加入到CICS域里,命令行代码为:
cicsadd -c pd -r nmas \
-B ${SS1} PathName=${SS2} RSLKey="public"
其中:
-c pd表示加入一个程序定义
-r nmas表示CICS域的名称(nmas为管理员定义)
-B表示同时修改永久库和运行库
${SS1}宏指出该程序在CICS域中的名称(唯一)
${SS2}宏指出程序的名称(全路径)
RSLKey="public"表示任何进程均可访问该资源
又如,从CICS的nmas域中删除一个程序定义的命令是:
cicsdelete –c pd –r nmas –B $(SS1)
其中:
-c pd表示加入一个程序定义
-r nmas表示CICS域的名称(nmas为管理员定义)
-B表示同时修改永久库和运行库
${SS1}宏指出该程序在CICS域中的名称(唯一)
含有CICS命令的C程序以.ccs作为后缀。每个CICS应用程序编写完成后,首先要使用CICS/6000提供的预编译工具进行预编译,然后才能编译和链接。如果该程序还含有ESQL语句,则对ESQL语句的预编译要在CICS语句预编译之后,具体过程如下:
编辑器 CICS程序 ESQL程序 C程序 可执行程序
CICS/6000应用程序预编译通过CICS提供的命令cicstran来完成,用法为:
cicstran –l C program
对CICS的封装是指根据一定的应用目的,将CICS API改写成便于书写、便于理解、便于移植的自定义的函数调用,而且调用封装后的函数可以独立于具体的CICS版本。外围程序只使用封装后的程序,还可以实现向其他通信中间件的移植。
对于CICS等第三方通信中间件产品的封装包括两个部分,即client端API的封装和server端API的封装。
对CICS的client端接口的封装,主要是将ECI_PARMS中的通用信息统一赋值,以简化调用的参数。封装是基于一定的应用系统的。
☆ CICSServerCall
将给定的交易包改善到服务器端,并从服务器端接收信息(存放在原交易包缓冲区内),函数原型为:
short CICSServerCall(char *strBuffer, short nLen, char *strServer,
char *strUser, char *strPassword,
char *strProgramName, short nTimeout);
入口参数:
char *strBuffer input/output buffer
short *nLen input buffer length
nLen==0时, 用缺省传送缓冲区长度
char *strServer CICS SERVER NAME
char *strUser CICS User Name
char *strPassword CICS User Password
char *strProgramName CICS 交易服务名
short nTimeout 呼叫等待时间
出口参数:
0 CICS交易正确返回
交易服务中SQL语句, 应用错, 由客户端程序自行检查
其他值 CICS交易错, 错误返回信息在strBuffer中
☆ UploadFile
将Client端文件通过缓冲区pBlockComm传输到服务端,函数原型为:
int UploadFile(char *strLocalFile, char *strServerFile);
入口参数:
strLocalFile: Client端文件名
strServerFile: 服务端文件名
支持服务端生成临时文件名, 格式: /dir1/dir2/filenameXXXXXX
生成的文件名返回到strServerFile中
可用GetValue(KEY_FILENAME, str)取到
出口参数:
0: 正确返回
!=0: 失败
☆ DownloadFile
将Server端文件通过缓冲区pBlockComm传输到Client端,函数原型为:
int DownloadFile(char *strLocalFile, char *strServerFile);
入口参数:
strLocalFile: Client端文件名
strServerFile: 服务端文件名
出口参数:
0: 正确返回
!=0: 失败
☆ InitBlockCics
初始化Cics服务端入口, 取传送缓冲区内容, 将传送缓冲区清空,函数原型为:
short InitBlockCics(void);
出口参数:
>0: 返回实际传送缓冲区的大小, 指针为pComm
其他: 出错
☆ ExitCics
Cics返回, 将缓冲区内容传给客户端,适用于无需大块数据传输,单纯的交易。注意: 返回缓冲区大小必须不大于传入缓冲区的大小。函数原型为:
void ExitCics(char *pTransBuf, short nLen);
入口参数:
pTransBuf: 需要传送回客户端的缓冲区的指针
nLen: 返回缓冲区的长度
☆ CicsCommit
交易提交。函数原型为:
void CicsCommit(void);
☆ CicsCommitAndReturn
交易提交并返回。函数原型为:
void CicsCommitAndReturn(char *pTransBuf, short nLen);
入口参数:
pTransBuf: 需要传送回客户端的缓冲区的指针
nLen: 返回缓冲区的长度
☆ CicsRollback
交易回滚。函数原型为:
void CicsRollback(void);
☆ CicsRollbackAndReturn
交易回滚并返回,函数原型为:
void CicsRollbackAndReturn(char *pTransBuf, short nLen);
pTransBuf: 需要传送回客户端的缓冲区的指针
nLen: 返回缓冲区的长度
出口参数: 无
☆ WriErrMsg
将程序发生的错误写入错误日志文件,函数原型为:
void WriErrMsg(const long lLine, const char *strFile,
const char *strFmt, ...);
入口参数:
nLine 错误索引号
strFile 程序或函数名