- 論壇徽章:
- 5
|
本帖最后由 pacman2000 于 2016-04-05 02:27 編輯
*異常處理
在核心系統(tǒng)開發(fā)和運(yùn)行中,異常處理是特別重要的一環(huán)。異常的規(guī)劃,對(duì)于系統(tǒng)的表現(xiàn)能力和查錯(cuò)能力有著巨大的作用,仔細(xì)的設(shè)計(jì)是十分值得的。
之前的報(bào)文格式中,提到Firebird的返回碼,是10位STRING。如果交易正常,返回碼為'OK',如果出錯(cuò),則為錯(cuò)誤代碼。如果為AS400系統(tǒng)級(jí)錯(cuò)誤,則為F+系統(tǒng)錯(cuò)誤代碼,如FCPF3282。如果是應(yīng)用錯(cuò)誤,則為E+應(yīng)用錯(cuò)誤代碼,如ECNBRNORL。另外,在返回報(bào)文中,還返回出錯(cuò)的程序源文件名,以及如果是系統(tǒng)錯(cuò)誤,要在日志中記錄出錯(cuò)的代碼行號(hào),訪問(wèn)的物理文件或者邏輯文件名等備查。
應(yīng)用部分的出錯(cuò)信息處理比較簡(jiǎn)單。Firebird沒有使用MSGF,而是普通的PF定義錯(cuò)誤代碼表,里面使用&1到&9用于文本的替換。應(yīng)用的錯(cuò)誤代碼根據(jù)模塊適用范圍,定義為E+[一級(jí)模塊]+[二級(jí)模塊]+錯(cuò)誤代碼,通用的錯(cuò)誤代碼模塊名可以省略。例如,EALEX表示“&1中&2記錄已經(jīng)存在”,ECNCMATDC表示“賬戶的余額性質(zhì)&1和余額方向&2不符”。在RPGLE程序中報(bào)應(yīng)用錯(cuò)誤的示例如下。
- /FREE
- CHAIN K_CNTLMF ACNTLMF.RACNTLMF R_CNTLMF1;
- IF %FOUND(ACNTLMF); //柜員已存在報(bào)錯(cuò)
- PMG.BKMSID = 'EALEX';
- A_MSDS(1) = C_MGTLMF;
- A_MSDS(2) = C_MGTLNO + TLADF1.BKTLNO;
- EXSR #ERR;
- ENDIF;
- /END-FREE
- **********************************************************************
- ** #ERR 取錯(cuò)誤信息
- **********************************************************************
- C #ERR BEGSR
- **
- C EVAL PMG.MSFLNM = PG_SRCMBR
- C IF PMG.BKMSDS = *BLANKS
- C CALL 'SCNCMMG'
- C PARM PMG
- C PARM A_MSDS
- C ENDIF
- C EXSR #EXIT
- **
- C ENDSR
- **********************************************************************
復(fù)制代碼 其中PMG結(jié)構(gòu)保存了錯(cuò)誤代碼,報(bào)錯(cuò)文件名,錯(cuò)誤描述,在#ERR這個(gè)公用過(guò)程中,調(diào)用了SCNCMMG程序,以A_MSDS數(shù)組對(duì)&1到&9進(jìn)行了替換,結(jié)果放在PMG.BKMSDS中,層層傳遞到最外層主控程序。PMG.MSFLNM使用的是PSDS結(jié)構(gòu),這個(gè)在接下來(lái)會(huì)有介紹。還記得V7R1中的新增內(nèi)置函數(shù)%SCANRPL嗎,用于錯(cuò)誤信息替換正合適,V6R1就只能自己寫一大段處理程序了。
相對(duì)于應(yīng)用報(bào)錯(cuò)的寫法,RPGLE程序中系統(tǒng)錯(cuò)誤的捕獲和處理就有技巧得多。要做到使得應(yīng)用程序簡(jiǎn)單,又不縮減錯(cuò)誤信息,還要不遺漏所有出錯(cuò)場(chǎng)景處理,并不容易。在RPGLE程序中,處理異常通常有4種方法,有置出錯(cuò)指示器,(E)加%ERROR內(nèi)置函數(shù),設(shè)置錯(cuò)誤處理過(guò)程,MONITOR和ON-ERROR語(yǔ)句組。前兩種是以往系統(tǒng)常見的寫法,但是應(yīng)用程序就不好看,大段的系統(tǒng)錯(cuò)誤處理把正常邏輯都淹沒了。因此,F(xiàn)irebird選用了對(duì)應(yīng)用最透明的錯(cuò)誤處理過(guò)程寫法,達(dá)到絕大多數(shù)情況無(wú)需應(yīng)用關(guān)注即可捕獲異常組織錯(cuò)誤信息,如果有特殊處理,則可結(jié)合(E)加%ERROR使用,滿足特殊要求。下面分別詳細(xì)介紹程序錯(cuò)誤和文件錯(cuò)誤的錯(cuò)誤處理過(guò)程。
程序錯(cuò)誤的捕獲和報(bào)錯(cuò),在RPGLE中使用的是PSDS自動(dòng)結(jié)構(gòu),以及*PSSR異常處理過(guò)程。即在遇到錯(cuò)誤時(shí),系統(tǒng)自動(dòng)會(huì)設(shè)置PSDS結(jié)構(gòu)內(nèi)容,并調(diào)用*PSSR過(guò)程。
- **程序狀態(tài)結(jié)構(gòu)
- DRPGPSDS SDS
- D PG_MAINPROC 1 10A
- D PG_STATUS 11 15A
- D PG_PRVSTAT 16 20A
- D PG_SRCLINE 21 28A
- D PG_ROUTINE 29 36A
- D PG_PARMNUM 37 39S 0
- D PG_MSID 40 46A
- D PG_PGMLIB 81 90A
- D PG_EXCPDT 91 170A
- D PG_LSERRFL 175 184A
- D PG_JOBDATE 191 198A
- D PG_FLINFO 209 243A
- D PG_JOBNAME 244 253A
- D PG_JOBUSER 254 263A
- D PG_JOBNUM 264 269S 0
- D PG_RUNDATE 276 281S 0
- D PG_RUNTIME 282 287S 0
- D PG_SRCFILE 304 313A
- D PG_SRCLIB 314 323A
- D PG_SRCMBR 324 333A
- D PG_PGMNAME 334 343A
- D PG_MODNAME 344 353A
- D PG_SRCLNADD 354 355B 0
- D PG_FLILNADD 356 357B 0
- D PG_USRPRF 358 367A
- D PG_EXTERR 368 371I 0
- **********************************************************************
- **特殊變量
- **是否執(zhí)行過(guò)錯(cuò)誤處理程序
- DPG_ERYNFG S LIKE(DICT.@@YNFG) INZ(YNFG_NO)
- **********************************************************************
- ** *PSSR程序異常處理
- **********************************************************************
- C *PSSR BEGSR
- **
- C IF PG_ERYNFG = YNFG_NO
- C EVAL PG_ERYNFG = YNFG_YES
- C EVAL PMG.MSFLNM = PG_SRCMBR
- C EVAL PMG.MSCDLN = PG_SRCLINE
- C EVAL PMG.BKMSID = 'F' + PG_MSID
- C EVAL PMG.BKMSDS = PG_EXCPDT
- C EVAL PMG.OTMSDS = PG_STATUS+' '+PG_PGMLIB+' '+
- C PG_PGMNAME
- C EXSR #EXIT
- C ENDIF
- **
- C ENDSR
- **********************************************************************
復(fù)制代碼 注意這里為了簡(jiǎn)化,PSDS沒有定義為QUALIFIED。PG_ERYNFG的作用,是為了防止錯(cuò)誤處理程序的多次重入(避免錯(cuò)誤程序中又拋出系統(tǒng)異常,導(dǎo)致無(wú)限遞歸)。
*PSSR過(guò)程中,通過(guò)結(jié)合PSDS結(jié)構(gòu),直接設(shè)置了系統(tǒng)異常錯(cuò)誤代碼(前面加了'F'),出錯(cuò)源文件名,出錯(cuò)源碼行號(hào),異常信息,以及附加信息,做到了報(bào)錯(cuò)信息組織的全自動(dòng)化。
文件錯(cuò)誤的捕獲和報(bào)錯(cuò),相對(duì)就復(fù)雜一些。在RPGLE中使用的是INFDS自動(dòng)結(jié)構(gòu),以及INFSR異常處理過(guò)程。即在遇到錯(cuò)誤時(shí),系統(tǒng)根據(jù)F表定義文件時(shí)指定的名字,自動(dòng)會(huì)設(shè)置INFDS結(jié)構(gòu)內(nèi)容,并調(diào)用INFSR過(guò)程。但是,這里有特例,如果在F表時(shí)就有錯(cuò)誤(比如自動(dòng)打開的文件不存在),那么仍然會(huì)執(zhí)行系統(tǒng)默認(rèn)異常處理而造成MSGW,這時(shí)候就需要外層主控進(jìn)行捕獲處理了。示例代碼節(jié)選如下。
- FCCNTLCA IF E K DISK INFSR(#FLEX) INFDS(S_CNTLCA)
- F QUALIFIED
- FACNTLTC UF A E K DISK COMMIT QUALIFIED
- F INFSR(#FLEX) INFDS(S_CNTLTC)
- **********************************************************************
- **記錄被鎖錯(cuò)誤信息
- DC_MGLOCK C CONST('記錄被鎖')
- **文件狀態(tài)結(jié)構(gòu)
- DFILESDS DS BASED(FILEDSP)
- D FL_FILE 1 8A
- D FL_OPNIND 9 9A
- D FL_EOFIND 10 10A
- D FL_STATUS 11 15S 0
- D FL_OPCODE 16 21A
- D FL_ROUTINE 22 29A
- D FL_SRCLINE 30 37A
- D FL_RECORD 38 45A
- D FL_MSID 46 52A
- D FL_SRCLNADD 77 78B 0
- D FL_ODPTYPE 81 82A
- D FL_FILENAME 83 92A
- D FL_LIBRARY 93 102A
- D FL_SPLFILE 103 112A
- D FL_SPLLIB 113 122A
- D FL_RCDLEN 125 126I 0
- D FL_KEYLEN 127 128I 0
- D FL_MEMBER 129 138A
- D FL_TYPE 147 148I 0
- D FL_RCDNUM 156 159I 0
- D FL_SPLNUM 160 163I 0
- D FL_OVERFLOW 188 189I 0
- D FL_BASEDMBRS 211 212I 0
- D FL_OPENID 214 215B 0
- D FL_RCDFMTLEN 216 217I 0
- D FL_CCSID 218 219I 0
- D FL_FBSIZE 367 370I 0
- D FL_KEYNUM 387 388I 0
- D FL_FBKEYLEN 393 394I 0
- D FL_MBRNUM 395 396I 0
- D FL_RRN 397 400I 0
- D FL_KEY 401 2400A
- **文件狀態(tài)結(jié)構(gòu)指針
- DFILEDSP S *
- **
- DS_CNTLCA DS LIKEDS(FILESDS)
- DR_CNTLCA DS LIKEREC(CCNTLCA.RCCNTLCA:*INPUT)
- DK_CNTLCA DS LIKEREC(CCNTLCA.RCCNTLCA:*KEY)
- **
- DS_CNTLTC DS LIKEDS(FILESDS)
- DR_CNTLTC1 DS LIKEREC(ACNTLTC.RACNTLTC:*INPUT)
- DR_CNTLTC2 DS LIKEREC(ACNTLTC.RACNTLTC:*OUTPUT)
- DK_CNTLTC DS LIKEREC(ACNTLTC.RACNTLTC:*KEY)
- **
- /FREE
- CLEAR R_CNTLCA; //取角色表信息
- CLEAR K_CNTLCA;
- FILEDSP = %ADDR(S_CNTLCA);
- K_CNTLCA.BKCHGN = TLADF3.ARR(V_RECD1).BKCHGN ;
- CHAIN %KDS(K_CNTLCA) CCNTLCA.RCCNTLCA R_CNTLCA ;
- IF NOT %FOUND(CCNTLCA);
- PMG.BKMSID = 'ENTRD';
- A_MSDS(1) = C_MGTLCA;
- A_MSDS(2) = C_MGCHGN + TLADF3.ARR(V_RECD1).BKCHGN;
- EXSR #ERR;
- ENDIF;
- /END-FREE
- **********************************************************************
- ** #FLEX文件異常處理
- **********************************************************************
- C #FLEX BEGSR
- **
- C EVAL PMG.MSFLNM = PG_SRCMBR
- C EVAL PMG.MSCDLN = FL_SRCLINE
- C EVAL PMG.BKMSID = 'F' + FL_MSID
- C IF FL_STATUS = 1218
- C CALL 'GETOBJTXT'
- C PARM FL_LIBRARY V_FLEXLIB 10
- C PARM FL_FILENAME V_FLEXOBJ 10
- C PARM '*FILE' V_FLEXTYP 7
- C PARM *BLANKS V_FLEXTEXT 50
- C EVAL PMG.BKMSDS = %TRIM(V_FLEXTEXT) +
- C %TRIM(FL_FILENAME) + '.' +
- C %TRIM(FL_MEMBER) + C_MGLOCK +
- C ',' + PG_EXCPDT
- C ELSE
- C EVAL PMG.BKMSDS = PG_EXCPDT
- C ENDIF
- C EVAL PMG.OTMSDS = PG_FLINFO
- C EXSR #EXIT
- **
- C ENDSR
- **********************************************************************
復(fù)制代碼 這段就需要解釋一下了。首先,F(xiàn)表定義的多個(gè)文件,INFSR可以共用一個(gè),但I(xiàn)NFDS系統(tǒng)要求是不能共享的,必須每個(gè)文件定義一份。為了#FLEX的通用寫法,因此對(duì)FILESDS指定了一個(gè)指針FILEDSP,每次在文件操作前,程序中像這樣FILEDSP = %ADDR(S_CNTLCA)設(shè)置指針指向要操作文件對(duì)應(yīng)的FILESDS結(jié)構(gòu)。然后如果后續(xù)的文件操作出錯(cuò),F(xiàn)ILEDSP指向被自動(dòng)填充的文件結(jié)構(gòu),系統(tǒng)執(zhí)行#FLEX過(guò)程,類似程序異常一樣做到了報(bào)錯(cuò)信息組織的全自動(dòng)化。這里特別注意對(duì)于錯(cuò)誤狀態(tài)1218,即文件記錄被鎖定超時(shí),拋出的錯(cuò)誤帶經(jīng)過(guò)GETOBJTXT轉(zhuǎn)換的PF中文注釋,形如“柜員角色表CCNTLCA.CCNTLCA記錄被鎖”,對(duì)渠道端錯(cuò)誤信息展示更友好。
- /*BEGIN***************************************************************/
- /*程序名稱:GETOBJTXT */
- /*功能描述: */
- /* */
- /*設(shè)計(jì)人員:PACMAN 開發(fā)人員:PACMAN */
- /*設(shè)計(jì)日期:2014-11-27 開發(fā)日期:2014-11-27 */
- /*-------------------------------------------------------------------*/
- /*維護(hù)人員: */
- /*維護(hù)日期: */
- /*維護(hù)內(nèi)容: */
- /* */
- /*END*****************************************************************/
- PGM PARM(&LIBNM &OBJNM &OBJTP &TEXT)
- INCLUDE SRCMBR(CLHD) SRCFILE(DSCPPGM)
- DCL VAR(&LIBNM) TYPE(*CHAR) LEN(10)
- DCL VAR(&OBJNM) TYPE(*CHAR) LEN(10)
- DCL VAR(&OBJTP) TYPE(*CHAR) LEN(7)
- DCL VAR(&TEXT) TYPE(*CHAR) LEN(50)
- IF COND(&LIBNM *EQ ' ') THEN(DO)
- CHGVAR VAR(&LIBNM) VALUE('*LIBL')
- ENDDO
- RTVOBJD OBJ(&LIBNM/&OBJNM) OBJTYPE(&OBJTP) TEXT(&TEXT)
- MONMSG MSGID(CPF0000)
- ENDPGM: ENDPGM
復(fù)制代碼 在真正的組件和交易程序中,PSDS,F(xiàn)ILESDS結(jié)構(gòu)都封裝到/COPY的PGDS中,#ERR,*PSSR,#FLEX都封裝到/COPY的PGCM中,應(yīng)用程序篇幅就簡(jiǎn)化了很多。
通過(guò)*PSSR和#FLEX解決了大部分問(wèn)題,但最后還遺留了一點(diǎn)會(huì)造成MSGW的未能捕獲的異常。這種情況顯然也不能放過(guò),就需要更高級(jí)的主控程序處理了。聯(lián)機(jī)交易主控程序MONSVR會(huì)掃描監(jiān)視真正執(zhí)行的JOBSVR,結(jié)束掉MSGW的JOBSVR并記錄出錯(cuò)信息,然后重新啟動(dòng)一個(gè)新的代替。MONSVR代碼片段如下。
- /*保存最大啟動(dòng)進(jìn)程數(shù)*/
- arr[0]=num;
- freenum=num;
- /*監(jiān)測(cè)子進(jìn)程是否正常*/
- for (i=arr[0];i>=1;i--)
- {
- if (arr[i]!=0)
- {
- char reason[3009];
- memset(reason, 0, sizeof(reason));
- rc=checkJob(arr[i], reason);
- if (rc==1)
- {
- if (i<=num && new_reg_ver!=0)
- writeLog("WARNING", JOBNAME, __FILE__, __LINE__,
- "任務(wù)S%05d%03d %d不存在", port, i, arr[i]);
- else
- debugLog(svrdebug, JOBNAME, __FILE__, __LINE__,
- "任務(wù)S%05d%03d %d已退出", port, i, arr[i]);
- arr[i]=0;
- }
- else if (rc==2)
- {
- writeLog("INFO", JOBNAME, __FILE__, __LINE__,
- "任務(wù)S%05d%03d %d已出錯(cuò):%s", port, i, arr[i],
- reason);
- if (!svrdebug)
- {
- endJob(arr[i]);
- arr[i]=0;
- }
- }
- else if (rc==3)
- freenum++;
- }
- if (i==arr[0] && arr[i]==0)
- arr[0]--;
- }
- /*保存最大啟動(dòng)進(jìn)程數(shù)*/
- arr[0] = arr[0]>num ? arr[0] : num;
- /*檢驗(yàn)進(jìn)程是否存在并啟動(dòng)*/
- for (i=1;i<=num;i++)
- {
- if (arr[i]==0)
- {
- sprintf(jobname,"S%05d%03d",port,i);
- sprintf(argstr, "%d %d %d %d %d %d", port, savedate,
- reg_ver, reg_num, i, bakmode);
- pid=spawn(pathstr, 1, spawn_fdmap, &inherit, spawn_argv,
- spawn_envp);
- if (pid<0)
- {
- writeLog("WARNING", JOBNAME, __FILE__, __LINE__, "重啟%s出錯(cuò)%d",
- jobname, errno);
- arr[i]=0;
- }
- else
- {
- arr[i]=pid;
- debugLog(svrdebug, JOBNAME, __FILE__, __LINE__,
- "重啟%s成功%d", jobname, pid);
- }
- }
- }
復(fù)制代碼 其中重要的是這么幾點(diǎn),checkJob()用于檢查某個(gè)pid進(jìn)程的狀態(tài),如果MSGW則獲取詳細(xì)出錯(cuò)信息到reason字符串中。endJob()用于結(jié)束一個(gè)pid進(jìn)程。spawn()函數(shù)產(chǎn)生一個(gè)進(jìn)程執(zhí)行指定的程序。通過(guò)writeLog(),MONSVR將出錯(cuò)的進(jìn)程和錯(cuò)誤信息寫到主控日志備查。下面是checkJob和endJob的代碼。
- /*BEGIN***************************************************************/
- /*程序名稱:JOBCTL */
- /*功能描述:任務(wù)相關(guān)的調(diào)用封裝 */
- /* */
- /*設(shè)計(jì)人員:PACMAN 開發(fā)人員:PACMAN */
- /*設(shè)計(jì)日期:2011-11-11 開發(fā)日期:2011-11-11 */
- /*-------------------------------------------------------------------*/
- /*維護(hù)人員: */
- /*維護(hù)日期: */
- /*維護(hù)內(nèi)容: */
- /* */
- /*END*****************************************************************/
- #include <string.h>
- #include <sys/types.h>
- #include <qp0wpid.h>
- #include "dscppgm/cpyrgt_h"
- extern void ENDJOBCL(char *jobnb, char *usrnm, char*jobnm);
- extern void GETJOBCL(char *jobnb, char *usrnm, char*jobnm, char *rtcd,
- char *reason);
- /*返回1表示未找到,返回2表示MSGW*/
- int checkJob(pid_t pid, char *reason)
- {
- QP0W_Job_ID_T jobinfo;
- int ret;
- char rtcd[1];
- ret=Qp0wGetJobID(pid, &jobinfo);
- if (ret!=0)
- return 1;
- GETJOBCL(jobinfo.jobnumber, jobinfo.username, jobinfo.jobname, rtcd,
- reason);
- return rtcd[0]-'0';
- }
- int endJob(pid_t pid)
- {
- QP0W_Job_ID_T jobinfo;
- int ret;
- ret=Qp0wGetJobID(pid, &jobinfo);
- if (ret!=0)
- return ret;
- ENDJOBCL(jobinfo.jobnumber, jobinfo.username, jobinfo.jobname);
- return 0;
- }
- int getJobname(pid_t pid, char *name)
- {
- QP0W_Job_ID_T jobinfo;
- int ret;
- ret=Qp0wGetJobID(pid, &jobinfo);
- if (ret!=0)
- return ret;
- strncpy(name, jobinfo.jobname, 10);
- name[10]='\0';
- return 0;
- }
復(fù)制代碼 里面使用了GETJOBCL和ENDJOBCL這兩個(gè)CL程序。代碼如下。
- /*BEGIN***************************************************************/
- /*程序名稱:GETJOBCL */
- /*功能描述:獲取指定任務(wù)的運(yùn)行狀態(tài) */
- /* RTCD 返回狀態(tài) */
- /* '0' 正常 */
- /* '1' 未找到 */
- /* '2' MSGW */
- /* '3' TIMW或TIMA */
- /* REASON MSGW原因,前7位為MSGID后3000字節(jié)為原因 */
- /* */
- /*設(shè)計(jì)人員:PACMAN 開發(fā)人員:PACMAN */
- /*設(shè)計(jì)日期:2011-11-11 開發(fā)日期:2011-11-11 */
- /*-------------------------------------------------------------------*/
- /*維護(hù)人員: */
- /*維護(hù)日期: */
- /*維護(hù)內(nèi)容: */
- /* */
- /*END*****************************************************************/
- PGM PARM(&JOBNUM &USRNAM &JOBN &RTCD &REASON)
- INCLUDE SRCMBR(CLHD) SRCFILE(DSCPPGM)
- DCL VAR(&JOBNUM) TYPE(*CHAR) LEN(6)
- DCL VAR(&USRNAM) TYPE(*CHAR) LEN(10)
- DCL VAR(&JOBN) TYPE(*CHAR) LEN(10)
- DCL VAR(&RTCD) TYPE(*CHAR) LEN(1)
- DCL VAR(&JOBINF) TYPE(*CHAR) LEN(225)
- DCL VAR(&JOBST) TYPE(*CHAR) LEN(10)
- DCL VAR(&JOBACTST) TYPE(*CHAR) LEN(4)
- DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4)
- DCL VAR(&MSGQUE) TYPE(*CHAR) LEN(10)
- DCL VAR(&MSGLIB) TYPE(*CHAR) LEN(10)
- DCL VAR(&MSGASP) TYPE(*CHAR) LEN(10)
- DCL VAR(&JOBNAM) TYPE(*CHAR) LEN(26)
- DCL VAR(&SENDER) TYPE(*CHAR) LEN(80)
- DCL VAR(&REASON) TYPE(*CHAR) LEN(3008)
- DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
- DCL VAR(&MSGHLP) TYPE(*CHAR) LEN(3000)
- CHGVAR VAR(&RTCD) VALUE('0')
- CHGVAR VAR(&JOBNAM) VALUE(&JOBN *CAT &USRNAM *CAT +
- &JOBNUM)
- CHGVAR VAR(&SENDER) VALUE(&JOBNAM)
- CALL PGM(QUSRJOBI) PARM(&JOBINF X'000000D1' +
- 'JOBI0200' &JOBNAM ' ')
- MONMSG MSGID(CPF3C51 FPF3C52 CPF3C53 CPF3C54 +
- CPF3C55) EXEC(DO)
- CHGVAR VAR(&RTCD) VALUE('1')
- GOTO CMDLBL(END)
- ENDDO
- CHGVAR VAR(&JOBST) VALUE(%SST(&JOBINF 51 10))
- CHGVAR VAR(&JOBACTST) VALUE(%SST(&JOBINF 108 4))
- IF COND(&JOBACTST *EQ 'MSGW') THEN(DO)
- CHGVAR VAR(&RTCD) VALUE('2')
- CHGVAR VAR(&MSGKEY) VALUE(%SST(&JOBINF 192 4))
- CHGVAR VAR(&MSGQUE) VALUE(%SST(&JOBINF 196 10))
- CHGVAR VAR(&MSGLIB) VALUE(%SST(&JOBINF 206 10))
- CHGVAR VAR(&MSGASP) VALUE(%SST(&JOBINF 216 10))
- RCVMSG MSGQ(&MSGQUE) MSGTYPE(*INQ) RMV(*NO) +
- MSGKEY(&MSGKEY) SECLVL(&MSGHLP) +
- MSGID(&MSGID) +
- SENDER(&SENDER) SENDERFMT(*SHORT)
- MONMSG MSGID(CPF0000) EXEC(DO)
- GOTO CMDLBL(END)
- ENDDO
- CHGVAR VAR(&REASON) VALUE(&MSGID *CAT ':' *CAT +
- &MSGHLP)
- GOTO CMDLBL(END)
- ENDDO
- IF COND((&JOBACTST *EQ 'TIMW') *OR (&JOBACTST +
- *EQ 'TIMA')) THEN(DO)
- CHGVAR VAR(&RTCD) VALUE('3')
- ENDDO
- END:
- ENDPGM
復(fù)制代碼
- /*BEGIN***************************************************************/
- /*程序名稱:ENDJOBCL */
- /*功能描述:結(jié)束指定任務(wù) */
- /* */
- /*設(shè)計(jì)人員:PACMAN 開發(fā)人員:PACMAN */
- /*設(shè)計(jì)日期:2011-11-11 開發(fā)日期:2011-11-11 */
- /*-------------------------------------------------------------------*/
- /*維護(hù)人員: */
- /*維護(hù)日期: */
- /*維護(hù)內(nèi)容: */
- /* */
- /*END*****************************************************************/
- PGM PARM(&JOBNB &USRNM &JOBNM)
- INCLUDE SRCMBR(CLHD) SRCFILE(DSCPPGM)
- DCL VAR(&JOBNB) TYPE(*CHAR) LEN(6)
- DCL VAR(&USRNM) TYPE(*CHAR) LEN(10)
- DCL VAR(&JOBNM) TYPE(*CHAR) LEN(10)
- ENDJOB JOB(&JOBNB/&USRNM/&JOBNM) OPTION(*IMMED)
- MONMSG MSGID(CPF1321)
- ENDPGM
復(fù)制代碼 批處理的主控也是類似,使用GETJOBCL和ENDJOBCL進(jìn)行批量任務(wù)分段JOB的監(jiān)視和錯(cuò)誤登記,這里就不再贅述了。
通過(guò)主控,RPGLE程序?qū)訉影殃P(guān),以及統(tǒng)一的錯(cuò)誤處理程序,F(xiàn)irebird減輕了應(yīng)用開發(fā)人員的錯(cuò)誤處理負(fù)擔(dān),并且讓錯(cuò)誤信息更為友好,盡可能的保存了錯(cuò)誤的豐富信息,這對(duì)于系統(tǒng)的維護(hù)可以帶來(lái)很大的幫助。而這些,正是系統(tǒng)設(shè)計(jì)時(shí)就需要重視并在整體架構(gòu)里考慮,才能做好的。
|
|