Chinaunix
标题:
为什么这段文章回复以后就不见了?
[打印本页]
作者:
pacman2000
时间:
2016-04-11 01:50
标题:
为什么这段文章回复以后就不见了?
自己写的一段文章,在连载中回复了好多次,每次贴进去就不见了。。。
作者:
pacman2000
时间:
2016-04-11 01:50
*面向对象实现
在核心系统这样大型的软件系统设计中,面向对象的设计方法,有助于分解复杂度,既保持抽象统一,又有灵活性。这里说的面向对象设计方法,不是指使用面向对象的编程语言就可以,而是指设计系统的思想。系统架构不进化,即使用Java这样的面向对象编程语言,也一样只会写出流水账似的程序。
面向对象的设计,主要体现在封装、继承、多态。封装表现为,系统应当进行合理的层次划分和粒度划分,识别出哪些是对象,并绑定对象的功能和属性。对照来看,产品工厂就是一种面向对象设计的典型场景。存贷等产品,对应编程语言的类,是一种抽象封装。用这个产品开立的具体账户,就是这个类的实例。产品可以定义各种使用功能,这个对应类的成员函数。产品的功能用到各种参数做逻辑控制,这个对应类的成员变量。最简单的基本产品,可以组合成组合产品,这个类似于多个类组合成新的类。产品的定义有层次关系,例如存款产品--定期存款产品--整存整取--人民币整存整取--人民币一年期整存整取,这个就像类的继承关系。上层产品的参数和功能会继承到下层产品中。如果在产品继承时,下层产品差异化了功能的实现行为,这就是多态。产品工厂在RPGLE中的实现方法并不复杂。将参数按记录方式保存,取产品参数后,如果有账户层定制,读取账户参数值覆盖掉产品参数值,就实现了参数的继承。通过产品号的规则,可以体现产品层次关系,方便判断具体产品是否归属于某一类。产品的功能实现多态,可以按字符串方式保存组件名字,动态调用即可。
不过在Firebird中通过技术写法体现面向对象多态实现,在联机交易主控流程中更为明显。核心系统的联机交易,有一些步骤是所有交易共有的,如获取交易日期时间,获取流水号,机构柜员检查等等。因此,有必要定义通用的交易流程,简化交易应用程序的编写。一方面避免交易应用程序的处理遗漏,另一方面当需要新增或改动共有处理时,防止出现所有交易全面修改的情况。以前的系统,通常很少有共有交易流程,依赖于每个交易应用程序本身的检查处理完备性。在Firebird的主控中,细分出交易流程层,引入面向对象编程方法,将每个交易公共的步骤集中处理。交易主流程中,由两种类型的方法组成,一种是非覆盖方法,各交易不能取代重写,程序名为PPLMNN1到PPLMNN9,另一种是覆盖方法,默认程序名为SPLMNV1到SPLMNV9,可以由交易根据情况单独定制(根据程序名实现对应)。例如020001交易,交易处理程序名为T020001A,则交易主流程中可覆盖的多态方法名字则为T020001A1到T020001A9,分别覆盖SPLMNV1到SPLMNV9,如果未生成对应的多态程序,主控会调用默认程序,一旦生成了多态程序,无需进行配置,主控就会识别并调用交易自定义的多态程序。
下面展示在主控中如何组织交易主流程,实现识别覆盖方法。
/*BEGIN***************************************************************/
/*程序名称:TRANFUNC_H */
/*功能描述:通用交易声明 */
/* */
/*设计人员:PACMAN 开发人员:PACMAN */
/*设计日期:2011-11-11 开发日期:2011-11-11 */
/*-------------------------------------------------------------------*/
/*维护人员: */
/*维护日期: */
/*维护内容: */
/* */
/*END*****************************************************************/
#ifndef TRANFUNC_H
#define TRANFUNC_H
#include "msginfo_h"
typedef void (Tran1)(rpg_msg_info* msg, char* in, char* out);
#pragma linkage(Tran1, OS)
typedef void (Tran2)(rpg_msg_info* msg, char* in, char* out, char* fe);
#pragma linkage(Tran2, OS)
#endif
复制代码
这段头文件声明了两类RPGLE程序给主控调用,一类是参数不带收费数组的,一类是参数带收费数组的。根据处理内容的不同,主控流程中的方法都可以归到这两类中。
/*BEGIN***************************************************************/
/*程序名称:TRANFUNC */
/*功能描述:调度交易主流程程序 */
/* */
/*设计人员:PACMAN 开发人员:PACMAN */
/*设计日期:2011-11-11 开发日期:2011-11-11 */
/*-------------------------------------------------------------------*/
/*维护人员: */
/*维护日期: */
/*维护内容: */
/* */
/*END*****************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <except.h>
#include <mih/triml.h>
#include <mih/rslvsp.h>
#include "dscppgm/cpyrgt_h"
#include "config_h"
#include "tranfunc_h"
#include "msginfo_h"
extern void DBCTL(char*);
extern int trim_str(char *buf, const char *str, int len);
extern void get_msginfo(msg_info *, const rpg_msg_info *);
extern msg_info msginfo;
static int rsl_flag;
static char rsl_pgm[FILENM_LEN+1];
void RSLVSP_PGM_HDLR(_INTRPT_Hndlr_Parms_T *errmsg)
{
if(strncmp(errmsg->Msg_Id, "MCH3401", 7) == 0)
{
strcpy(msginfo.msgid, "EPLMNPGNF ");
sprintf(msginfo.msgtext, "调用程序%s未找到", rsl_pgm);
rsl_flag = 1;
}
else
{
strcpy(msginfo.msgid, "EPLMNPGER ");
sprintf(msginfo.msgtext, "查找程序%s时出错%7.7s",
rsl_pgm, errmsg->Msg_Id);
rsl_flag = 2;
}
}
int execute_rslvsp(char* pgm_nm, int type, Tran1** pt1, Tran2** pt2)
{
rsl_flag = 0;
strcpy(rsl_pgm, pgm_nm);
#pragma exception_handler (RSLVSP_PGM_HDLR,rsl_flag,0,_C2_MH_ESCAPE,\
_CTLA_HANDLE_NO_MSG)
if(type == 1)
*pt1 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
else
*pt2 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
#pragma disable_handler
return rsl_flag;
}
void clear_msg(void)
{
msginfo.msgid[0]='\0';
msginfo.msgtext[0]='\0';
}
int check_msgid(void)
{
if (triml(msginfo.msgid, ' ')!=0)
{
if (strncmp(msginfo.msgid, "EPLMNREST", 9)==0)
return 1;
else
return -1;
}
return 0;
}
int execute_overpgm(char* overwt, char* dft, int type,
char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type==1)
{
ret=execute_rslvsp(overwt, 1, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 1, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(overwt, 2, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 2, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int execute_pgm(char* pgm_nm, int type, char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type == 1)
{
ret=execute_rslvsp(pgm_nm, 1, &tran1, &tran2);
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(pgm_nm, 2, &tran1, &tran2);
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int process_tran(const char* tr_cd, char* tr_pgm,
char* in, char* out, char* fe, char flg)
{
char pgms[9][FILENM_LEN+1];
char trpgm[FILENM_LEN+1];
int ret=0, i;
if (trim_str(trpgm, tr_pgm, FILENM_LEN) > FILENM_LEN-1)
{
strcpy(msginfo.msgid, "EPLMNPGTL ");
sprintf(msginfo.msgtext, "交易程序名%s太长", trpgm);
return -2;
}
/*给该交易的每个覆盖方法赋值*/
for (i=0; i<9; i++)
sprintf(pgms[i], "%s%1d", trpgm, i+1);
for (;;)
{
/* 交易初始化*/
if (ret==0)
ret = execute_pgm("PPLMNN1", 1, in, out, fe);
/* 覆盖方法1交易预处理 */
if (ret==0)
ret = execute_overpgm(pgms[0], "SPLMNV1", 1, in, out, fe);
/* 柜员归属检查 */
if (ret==0)
ret = execute_pgm("PPLMNN2", 1, in, out, fe);
/* 覆盖方法2交易机构柜员检查*/
if (ret==0)
ret = execute_overpgm(pgms[1], "SPLMNV2", 1, in, out, fe);
/* 生成交易流水号*/
if (ret==0)
ret = execute_pgm("PPLMNN3", 1, in, out, fe);
/* 覆盖方法3交易收费计算*/
if (ret==0)
ret = execute_overpgm(pgms[2], "SPLMNV3", 2, in, out, fe);
/* 费用核对*/
if (ret==0)
ret = execute_pgm("PPLMNN4", 2, in, out, fe);
/* 调用交易程序*/
if (ret==0)
ret = execute_pgm(trpgm, 1, in, out, fe);
/* 调用费用收费并进行传票重整服务*/
if (ret==0)
ret = execute_pgm("PPLMNN5", 1, in, out, fe);
/* 覆盖方法4写输出接口*/
if (ret==0)
ret = execute_overpgm(pgms[3], "SPLMNV4", 1, in, out, fe);
/* 返回处理*/
if (ret==0)
ret = execute_pgm("PPLMNN6", 1, in, out, fe);
if (ret==0 && flg==DEBUG_NO)
DBCTL(DB_COMMIT);
else
DBCTL(DB_ROLLBACK);
if (ret!=1)
break;
clear_msg();
}
return ret;
}
复制代码
这段程序中,最重要的是rslvsp()这个系统函数,这个函数用来在指定的库列表中获取系统对象指针。在这里我们用来获取覆盖方法的*PGM程序对象。通过外面用#pragma exception_handler的包围,指定了RSLVSP_PGM_HDLR()作为rslvsp()的异常捕获函数,当捕获MCH3401时,即不存在程序对象。execute_rslvsp()这个函数的功能,就实现了获取指定名字的*PGM,设置指针变量,返回是否找到的标志。execute_overpgm()实现了如果有交易自定义覆盖方法程序存在,则调用,否则调用默认的程序。execute_pgm()实现了调用非覆盖方法。最后的process_tran()实现了交易主流程,依次按流程组织调用非覆盖方法和覆盖方法,进行事务回滚或提交。
注意交易主流程中,识别是否出现交易重新执行的特殊错误代码EPLMNREST,如果出现则原事务回滚并重新开始执行整个交易流程。这能解决一些特定场景,例如第三方来账如果入账不成功,需要直接挂待销账。通过修改输入结构的某些字段值,并返回EPLMNREST错误代码,这样在核心系统一次交易即可实现入账或挂账功能。
作者:
pacman2000
时间:
2016-04-11 01:50
我一点一点的贴进来看看。
作者:
pacman2000
时间:
2016-04-11 01:51
*面向对象实现
在核心系统这样大型的软件系统设计中,面向对象的设计方法,有助于分解复杂度,既保持抽象统一,又有灵活性。这里说的面向对象设计方法,不是指使用面向对象的编程语言就可以,而是指设计系统的思想。系统架构不进化,即使用Java这样的面向对象编程语言,也一样只会写出流水账似的程序。
面向对象的设计,主要体现在封装、继承、多态。封装表现为,系统应当进行合理的层次划分和粒度划分,识别出哪些是对象,并绑定对象的功能和属性。对照来看,产品工厂就是一种面向对象设计的典型场景。存贷等产品,对应编程语言的类,是一种抽象封装。用这个产品开立的具体账户,就是这个类的实例。产品可以定义各种使用功能,这个对应类的成员函数。产品的功能用到各种参数做逻辑控制,这个对应类的成员变量。最简单的基本产品,可以组合成组合产品,这个类似于多个类组合成新的类。产品的定义有层次关系,例如存款产品--定期存款产品--整存整取--人民币整存整取--人民币一年期整存整取,这个就像类的继承关系。上层产品的参数和功能会继承到下层产品中。如果在产品继承时,下层产品差异化了功能的实现行为,这就是多态。产品工厂在RPGLE中的实现方法并不复杂。将参数按记录方式保存,取产品参数后,如果有账户层定制,读取账户参数值覆盖掉产品参数值,就实现了参数的继承。通过产品号的规则,可以体现产品层次关系,方便判断具体产品是否归属于某一类。产品的功能实现多态,可以按字符串方式保存组件名字,动态调用即可。
不过在Firebird中通过技术写法体现面向对象多态实现,在联机交易主控流程中更为明显。核心系统的联机交易,有一些步骤是所有交易共有的,如获取交易日期时间,获取流水号,机构柜员检查等等。因此,有必要定义通用的交易流程,简化交易应用程序的编写。一方面避免交易应用程序的处理遗漏,另一方面当需要新增或改动共有处理时,防止出现所有交易全面修改的情况。以前的系统,通常很少有共有交易流程,依赖于每个交易应用程序本身的检查处理完备性。在Firebird的主控中,细分出交易流程层,引入面向对象编程方法,将每个交易公共的步骤集中处理。交易主流程中,由两种类型的方法组成,一种是非覆盖方法,各交易不能取代重写,程序名为PPLMNN1到PPLMNN9,另一种是覆盖方法,默认程序名为SPLMNV1到SPLMNV9,可以由交易根据情况单独定制(根据程序名实现对应)。例如020001交易,交易处理程序名为T020001A,则交易主流程中可覆盖的多态方法名字则为T020001A1到T020001A9,分别覆盖SPLMNV1到SPLMNV9,如果未生成对应的多态程序,主控会调用默认程序,一旦生成了多态程序,无需进行配置,主控就会识别并调用交易自定义的多态程序。
下面展示在主控中如何组织交易主流程,实现识别覆盖方法。
/*BEGIN***************************************************************/
/*程序名称:TRANFUNC_H */
/*功能描述:通用交易声明 */
/* */
/*设计人员:PACMAN 开发人员:PACMAN */
/*设计日期:2011-11-11 开发日期:2011-11-11 */
/*-------------------------------------------------------------------*/
/*维护人员: */
/*维护日期: */
/*维护内容: */
/* */
/*END*****************************************************************/
#ifndef TRANFUNC_H
#define TRANFUNC_H
#include "msginfo_h"
typedef void (Tran1)(rpg_msg_info* msg, char* in, char* out);
#pragma linkage(Tran1, OS)
typedef void (Tran2)(rpg_msg_info* msg, char* in, char* out, char* fe);
#pragma linkage(Tran2, OS)
#endif
复制代码
这段头文件声明了两类RPGLE程序给主控调用,一类是参数不带收费数组的,一类是参数带收费数组的。根据处理内容的不同,主控流程中的方法都可以归到这两类中。
作者:
pacman2000
时间:
2016-04-11 01:51
/*BEGIN***************************************************************/
/*程序名称:TRANFUNC */
/*功能描述:调度交易主流程程序 */
/* */
/*设计人员:PACMAN 开发人员:PACMAN */
/*设计日期:2011-11-11 开发日期:2011-11-11 */
/*-------------------------------------------------------------------*/
/*维护人员: */
/*维护日期: */
/*维护内容: */
/* */
/*END*****************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <except.h>
#include <mih/triml.h>
#include <mih/rslvsp.h>
#include "dscppgm/cpyrgt_h"
#include "config_h"
#include "tranfunc_h"
#include "msginfo_h"
extern void DBCTL(char*);
extern int trim_str(char *buf, const char *str, int len);
extern void get_msginfo(msg_info *, const rpg_msg_info *);
extern msg_info msginfo;
static int rsl_flag;
static char rsl_pgm[FILENM_LEN+1];
void RSLVSP_PGM_HDLR(_INTRPT_Hndlr_Parms_T *errmsg)
{
if(strncmp(errmsg->Msg_Id, "MCH3401", 7) == 0)
{
strcpy(msginfo.msgid, "EPLMNPGNF ");
sprintf(msginfo.msgtext, "调用程序%s未找到", rsl_pgm);
rsl_flag = 1;
}
else
{
strcpy(msginfo.msgid, "EPLMNPGER ");
sprintf(msginfo.msgtext, "查找程序%s时出错%7.7s",
rsl_pgm, errmsg->Msg_Id);
rsl_flag = 2;
}
}
int execute_rslvsp(char* pgm_nm, int type, Tran1** pt1, Tran2** pt2)
{
rsl_flag = 0;
strcpy(rsl_pgm, pgm_nm);
#pragma exception_handler (RSLVSP_PGM_HDLR,rsl_flag,0,_C2_MH_ESCAPE,\
_CTLA_HANDLE_NO_MSG)
if(type == 1)
*pt1 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
else
*pt2 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
#pragma disable_handler
return rsl_flag;
}
void clear_msg(void)
{
msginfo.msgid[0]='\0';
msginfo.msgtext[0]='\0';
}
int check_msgid(void)
{
if (triml(msginfo.msgid, ' ')!=0)
{
if (strncmp(msginfo.msgid, "EPLMNREST", 9)==0)
return 1;
else
return -1;
}
return 0;
}
int execute_overpgm(char* overwt, char* dft, int type,
char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type==1)
{
ret=execute_rslvsp(overwt, 1, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 1, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(overwt, 2, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 2, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int execute_pgm(char* pgm_nm, int type, char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type == 1)
{
ret=execute_rslvsp(pgm_nm, 1, &tran1, &tran2);
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(pgm_nm, 2, &tran1, &tran2);
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int process_tran(const char* tr_cd, char* tr_pgm,
char* in, char* out, char* fe, char flg)
{
char pgms[9][FILENM_LEN+1];
char trpgm[FILENM_LEN+1];
int ret=0, i;
if (trim_str(trpgm, tr_pgm, FILENM_LEN) > FILENM_LEN-1)
{
strcpy(msginfo.msgid, "EPLMNPGTL ");
sprintf(msginfo.msgtext, "交易程序名%s太长", trpgm);
return -2;
}
/*给该交易的每个覆盖方法赋值*/
for (i=0; i<9; i++)
sprintf(pgms[i], "%s%1d", trpgm, i+1);
for (;;)
{
/* 交易初始化*/
if (ret==0)
ret = execute_pgm("PPLMNN1", 1, in, out, fe);
/* 覆盖方法1交易预处理 */
if (ret==0)
ret = execute_overpgm(pgms[0], "SPLMNV1", 1, in, out, fe);
/* 柜员归属检查 */
if (ret==0)
ret = execute_pgm("PPLMNN2", 1, in, out, fe);
/* 覆盖方法2交易机构柜员检查*/
if (ret==0)
ret = execute_overpgm(pgms[1], "SPLMNV2", 1, in, out, fe);
/* 生成交易流水号*/
if (ret==0)
ret = execute_pgm("PPLMNN3", 1, in, out, fe);
/* 覆盖方法3交易收费计算*/
if (ret==0)
ret = execute_overpgm(pgms[2], "SPLMNV3", 2, in, out, fe);
/* 费用核对*/
if (ret==0)
ret = execute_pgm("PPLMNN4", 2, in, out, fe);
/* 调用交易程序*/
if (ret==0)
ret = execute_pgm(trpgm, 1, in, out, fe);
/* 调用费用收费并进行传票重整服务*/
if (ret==0)
ret = execute_pgm("PPLMNN5", 1, in, out, fe);
/* 覆盖方法4写输出接口*/
if (ret==0)
ret = execute_overpgm(pgms[3], "SPLMNV4", 1, in, out, fe);
/* 返回处理*/
if (ret==0)
ret = execute_pgm("PPLMNN6", 1, in, out, fe);
复制代码
作者:
pacman2000
时间:
2016-04-11 01:52
/*BEGIN***************************************************************/
/*程序名称:TRANFUNC */
/*功能描述:调度交易主流程程序 */
/* */
/*设计人员:PACMAN 开发人员:PACMAN */
/*设计日期:2011-11-11 开发日期:2011-11-11 */
/*-------------------------------------------------------------------*/
/*维护人员: */
/*维护日期: */
/*维护内容: */
/* */
/*END*****************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <except.h>
#include <mih/triml.h>
#include <mih/rslvsp.h>
#include "dscppgm/cpyrgt_h"
#include "config_h"
#include "tranfunc_h"
#include "msginfo_h"
extern void DBCTL(char*);
extern int trim_str(char *buf, const char *str, int len);
extern void get_msginfo(msg_info *, const rpg_msg_info *);
extern msg_info msginfo;
static int rsl_flag;
static char rsl_pgm[FILENM_LEN+1];
void RSLVSP_PGM_HDLR(_INTRPT_Hndlr_Parms_T *errmsg)
{
if(strncmp(errmsg->Msg_Id, "MCH3401", 7) == 0)
{
strcpy(msginfo.msgid, "EPLMNPGNF ");
sprintf(msginfo.msgtext, "调用程序%s未找到", rsl_pgm);
rsl_flag = 1;
}
else
{
strcpy(msginfo.msgid, "EPLMNPGER ");
sprintf(msginfo.msgtext, "查找程序%s时出错%7.7s",
rsl_pgm, errmsg->Msg_Id);
rsl_flag = 2;
}
}
int execute_rslvsp(char* pgm_nm, int type, Tran1** pt1, Tran2** pt2)
{
rsl_flag = 0;
strcpy(rsl_pgm, pgm_nm);
#pragma exception_handler (RSLVSP_PGM_HDLR,rsl_flag,0,_C2_MH_ESCAPE,\
_CTLA_HANDLE_NO_MSG)
if(type == 1)
*pt1 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
else
*pt2 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
#pragma disable_handler
return rsl_flag;
}
void clear_msg(void)
{
msginfo.msgid[0]='\0';
msginfo.msgtext[0]='\0';
}
int check_msgid(void)
{
if (triml(msginfo.msgid, ' ')!=0)
{
if (strncmp(msginfo.msgid, "EPLMNREST", 9)==0)
return 1;
else
return -1;
}
return 0;
}
int execute_overpgm(char* overwt, char* dft, int type,
char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type==1)
{
ret=execute_rslvsp(overwt, 1, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 1, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(overwt, 2, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 2, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int execute_pgm(char* pgm_nm, int type, char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type == 1)
{
ret=execute_rslvsp(pgm_nm, 1, &tran1, &tran2);
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(pgm_nm, 2, &tran1, &tran2);
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int process_tran(const char* tr_cd, char* tr_pgm,
char* in, char* out, char* fe, char flg)
{
char pgms[9][FILENM_LEN+1];
char trpgm[FILENM_LEN+1];
int ret=0, i;
if (trim_str(trpgm, tr_pgm, FILENM_LEN) > FILENM_LEN-1)
{
strcpy(msginfo.msgid, "EPLMNPGTL ");
sprintf(msginfo.msgtext, "交易程序名%s太长", trpgm);
return -2;
}
/*给该交易的每个覆盖方法赋值*/
for (i=0; i<9; i++)
sprintf(pgms[i], "%s%1d", trpgm, i+1);
复制代码
作者:
pacman2000
时间:
2016-04-11 01:52
/*BEGIN***************************************************************/
/*程序名称:TRANFUNC */
/*功能描述:调度交易主流程程序 */
/* */
/*设计人员:PACMAN 开发人员:PACMAN */
/*设计日期:2011-11-11 开发日期:2011-11-11 */
/*-------------------------------------------------------------------*/
/*维护人员: */
/*维护日期: */
/*维护内容: */
/* */
/*END*****************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <except.h>
#include <mih/triml.h>
#include <mih/rslvsp.h>
#include "dscppgm/cpyrgt_h"
#include "config_h"
#include "tranfunc_h"
#include "msginfo_h"
extern void DBCTL(char*);
extern int trim_str(char *buf, const char *str, int len);
extern void get_msginfo(msg_info *, const rpg_msg_info *);
extern msg_info msginfo;
static int rsl_flag;
static char rsl_pgm[FILENM_LEN+1];
void RSLVSP_PGM_HDLR(_INTRPT_Hndlr_Parms_T *errmsg)
{
if(strncmp(errmsg->Msg_Id, "MCH3401", 7) == 0)
{
strcpy(msginfo.msgid, "EPLMNPGNF "
;
sprintf(msginfo.msgtext, "调用程序%s未找到", rsl_pgm);
rsl_flag = 1;
}
else
{
strcpy(msginfo.msgid, "EPLMNPGER "
;
sprintf(msginfo.msgtext, "查找程序%s时出错%7.7s",
rsl_pgm, errmsg->Msg_Id);
rsl_flag = 2;
}
}
int execute_rslvsp(char* pgm_nm, int type, Tran1** pt1, Tran2** pt2)
{
rsl_flag = 0;
strcpy(rsl_pgm, pgm_nm);
#pragma exception_handler (RSLVSP_PGM_HDLR,rsl_flag,0,_C2_MH_ESCAPE,\
_CTLA_HANDLE_NO_MSG)
if(type == 1)
*pt1 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
else
*pt2 = rslvsp(_Program, pgm_nm, "*LIBL", _AUTH_OBJ_MGMT);
#pragma disable_handler
return rsl_flag;
}
void clear_msg(void)
{
msginfo.msgid[0]='\0';
msginfo.msgtext[0]='\0';
}
int check_msgid(void)
{
if (triml(msginfo.msgid, ' ')!=0)
{
if (strncmp(msginfo.msgid, "EPLMNREST", 9)==0)
return 1;
else
return -1;
}
return 0;
}
int execute_overpgm(char* overwt, char* dft, int type,
char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type==1)
{
ret=execute_rslvsp(overwt, 1, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 1, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(overwt, 2, &tran1, &tran2);
if (ret==1)
{
clear_msg();
ret=execute_rslvsp(dft, 2, &tran1, &tran2);
}
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int execute_pgm(char* pgm_nm, int type, char* in, char* out, char* fe)
{
Tran1 *tran1;
Tran2 *tran2;
rpg_msg_info rpginfo;
int ret;
memset(&rpginfo, ' ', sizeof(rpginfo));
if (type == 1)
{
ret=execute_rslvsp(pgm_nm, 1, &tran1, &tran2);
if (ret!=0)
return -2;
tran1(&rpginfo, in, out);
}
else
{
ret=execute_rslvsp(pgm_nm, 2, &tran1, &tran2);
if (ret!=0)
return -2;
tran2(&rpginfo, in, out, fe);
}
get_msginfo(&msginfo, &rpginfo);
return check_msgid();
}
int process_tran(const char* tr_cd, char* tr_pgm,
char* in, char* out, char* fe, char flg)
{
char pgms[9][FILENM_LEN+1];
char trpgm[FILENM_LEN+1];
int ret=0, i;
if (trim_str(trpgm, tr_pgm, FILENM_LEN) > FILENM_LEN-1)
{
strcpy(msginfo.msgid, "EPLMNPGTL "
;
sprintf(msginfo.msgtext, "交易程序名%s太长", trpgm);
return -2;
}
/*给该交易的每个覆盖方法赋值*/
for (i=0; i<9; i++)
sprintf(pgms[i], "%s%1d", trpgm, i+1);
for (;
{
/* 交易初始化*/
if (ret==0)
ret = execute_pgm("
PLMNN1", 1, in, out, fe);
/* 覆盖方法1交易预处理 */
if (ret==0)
ret = execute_overpgm(pgms[0], "SPLMNV1", 1, in, out, fe);
/* 柜员归属检查 */
if (ret==0)
ret = execute_pgm("
PLMNN2", 1, in, out, fe);
/* 覆盖方法2交易机构柜员检查*/
if (ret==0)
ret = execute_overpgm(pgms[1], "SPLMNV2", 1, in, out, fe);
/* 生成交易流水号*/
if (ret==0)
ret = execute_pgm("
PLMNN3", 1, in, out, fe);
/* 覆盖方法3交易收费计算*/
if (ret==0)
ret = execute_overpgm(pgms[2], "SPLMNV3", 2, in, out, fe);
/* 费用核对*/
if (ret==0)
ret = execute_pgm("
PLMNN4", 2, in, out, fe);
/* 调用交易程序*/
if (ret==0)
ret = execute_pgm(trpgm, 1, in, out, fe);
/* 调用费用收费并进行传票重整服务*/
if (ret==0)
ret = execute_pgm("
PLMNN5", 1, in, out, fe);
/* 覆盖方法4写输出接口*/
if (ret==0)
ret = execute_overpgm(pgms[3], "SPLMNV4", 1, in, out, fe);
/* 返回处理*/
if (ret==0)
ret = execute_pgm("
PLMNN6", 1, in, out, fe);
if (ret==0 && flg==DEBUG_NO)
DBCTL(DB_COMMIT);
else
DBCTL(DB_ROLLBACK);
if (ret!=1)
break;
clear_msg();
}
return ret;
}
作者:
pacman2000
时间:
2016-04-11 01:53
占位,这段代码贴不了。
作者:
pacman2000
时间:
2016-04-11 01:53
这段程序中,最重要的是rslvsp()这个系统函数,这个函数用来在指定的库列表中获取系统对象指针。在这里我们用来获取覆盖方法的*PGM程序对象。通过外面用#pragma exception_handler的包围,指定了RSLVSP_PGM_HDLR()作为rslvsp()的异常捕获函数,当捕获MCH3401时,即不存在程序对象。execute_rslvsp()这个函数的功能,就实现了获取指定名字的*PGM,设置指针变量,返回是否找到的标志。execute_overpgm()实现了如果有交易自定义覆盖方法程序存在,则调用,否则调用默认的程序。execute_pgm()实现了调用非覆盖方法。最后的process_tran()实现了交易主流程,依次按流程组织调用非覆盖方法和覆盖方法,进行事务回滚或提交。
注意交易主流程中,识别是否出现交易重新执行的特殊错误代码EPLMNREST,如果出现则原事务回滚并重新开始执行整个交易流程。这能解决一些特定场景,例如第三方来账如果入账不成功,需要直接挂待销账。通过修改输入结构的某些字段值,并返回EPLMNREST错误代码,这样在核心系统一次交易即可实现入账或挂账功能。
作者:
pacman2000
时间:
2016-04-11 01:54
当中一段代码看我发在博客里的吧。
http://blog.chinaunix.net/uid-283313-id-5699224.html
作者:
王楠w_n
时间:
2016-04-11 09:09
我帮您看看,可以是触发关键字,然后被论坛屏蔽掉了
回复
1#
pacman2000
作者:
王楠w_n
时间:
2016-04-11 09:12
您好,回复已帮您恢复了
回复
11#
王楠w_n
作者:
pacman2000
时间:
2016-04-11 22:18
回复
12#
王楠w_n
额,一下子恢复了太多啦,能删掉点么。
作者:
pacman2000
时间:
2016-04-11 22:23
好像CU没有删除自己回帖的功能啊。
作者:
王楠w_n
时间:
2016-04-12 09:27
可以哈,我把重复的都删掉
回复
13#
pacman2000
作者:
yjh777
时间:
2016-04-12 15:00
CU 的关键字过滤有没有 人工复核, 误杀率好像比较高啊,,
建议关键字匹配后,转给对应版块版主复核一下? 版主看没问题就一键恢复,这个技术人员应该不难实现吧?
@王楠w_n
作者:
王楠w_n
时间:
2016-04-12 15:06
我在后台可以人工审核,我看了下,一般被拦截的原因是:时间节点太紧凑,由于网络原因,可能连续发了好几条,被当成广告给拦截了,这个我可以跟技术修改下
回复
16#
yjh777
作者:
pacman2000
时间:
2016-04-12 22:42
王楠w_n 发表于 2016-04-12 09:27
可以哈,我把重复的都删掉回复 13# pacman2000
好的,把
http://bbs.chinaunix.net/thread-4178561-5-1.html
这个帖子,33楼以下都删除了吧。
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2