Chinaunix首页 | 论坛 | 博客
  • 博客访问: 354615
  • 博文数量: 90
  • 博客积分: 847
  • 博客等级: 准尉
  • 技术积分: 1373
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-02 10:54
个人简介

跌打滚爬中的小菜鸟...

文章分类

全部博文(90)

文章存档

2015年(5)

2013年(47)

2012年(38)

我的朋友

分类: 系统运维

2012-11-03 10:42:54

方法一
上代码先
 FMT FX FFilename++IPEASF.....L.....A.Device+.Keywords+++++++++++++++++++
        *************** Beginning of data *******************************
0001.00 FCUSTOMER  O    E             DISK    COMMIT                    
0002.00  *                                                              
0003.00 C                   EVAL      CUSNO=60004                        
0004.00 C                   EVAL      CUSNM='JOE NUM004'                
0005.00 C                   WRITE     RCUST                              
0006.00 C                   IF        NOT %ERROR                        
0007.00 C                   COMMIT                                      
0008.00 C     'DONE'        DSPLY                                        
0009.00 C                   ELSE                                        
0010.00 C                   ROLBK                                        
0011.00 C     'FAIL'        DSPLY                                        
0012.00 C                   ENDIF                                        
0013.00 C                   EVAL      *INLR=*ON                          
0014.00 C                   RETURN                                      
        ****************** End of data **********************************
如果直接调用这个程序则会遇到如下问题:
4>> CALL RPG22                                                              
    Commitment definition *N not valid for open of CUSTOMER.                
    Error message CPF4326 appeared during OPEN for file CUSTOMER.            
    Error message CPF4326 appeared during OPEN for file CUSTOMER (C S D F).  
  ? C                                                                        
    Error message CPF4326 appeared during OPEN for file CUSTOMER (C S D F).  
  ? C                                                                        
    Application error.  RNX1216 unmonitored by RPG22 at statement 0001000001,
      instruction X'0000'.                                                  
    Application error.  RNX1216 unmonitored by RPG22 at statement 0001000001,
      instruction X'0000'.                                                  
原因是事务控制需要使用【STRCMTCTL LCKLVL(*ALL)】命令开头,然后用【ENDCMTCTL】命令结尾!!
所以这种方法的争取使用应该是:
1. STRCMTCTL LCKLVL(*ALL)
2. CALL RPG22
3. ENDCMTCTL
很显然,这种方法很不智能啊,还得手动控制,太麻烦了。。。下面看方法二


方法二    在RPG中使用API自动开始和结束事务控制
先看代码
 FMT FX FFilename++IPEASF.....L.....A.Device+.Keywords+++++++++++++++++++++++
        *************** Beginning of data ***********************************
0001.00 FCUSTOMER  O    E             DISK    COMMIT                        
0002.00 F                                     USROPN                        
0003.00  *                                                                  
0004.00 DQCMDEXC          PR                  EXTPGM('QCMDEXC')              
0005.00 D COMMAND                      100A   CONST OPTIONS(*VARSIZE)        
0006.00 D LENGTH                        15P 5 CONST                          
0007.00  *                                                                  
0008.00 C                   CALLP     QCMDEXC('STRCMTCTL LCKLVL(*ALL)': 22)  
0009.00 C                   OPEN      CUSTOMER                              
0010.00 C                   EVAL      CUSNO= 65003                          
0011.00 C                   EVAL      CUSNM= 'JOE NUM7'                      
0012.00 C                   WRITE     RCUST                                  
0013.00 C                   IF        NOT %ERROR                            
0014.00 C                   COMMIT                                          
0015.00 C     'DONE'        DSPLY                                            
0016.00 C                   ELSE                                            
0017.00 C                   ROLBK                                            
0018.00 C     'FAIL'        DSPLY                                            
0019.00 C                   ENDIF                                            
0020.00 C                   CLOSE     CUSTOMER   
0021.00 C                   CALLP     QCMDEXC('ENDCMTCTL': 9)                   
0022.00 C                   EVAL      *INLR=*ON                  
0023.00 C                   RETURN                              
        ****************** End of data **************************
NND,这可是我摸索了好久才弄明白的。
虽然思路很简单,但写代码时问题就出来了。同样一个代码,放在不同的位置程序就不一定正确,并且ERROR LOG也不一定相同。。。下面讨论碰到的几个问题:
1. 如果不使用USROPN关键字,那么应该是不能在RPG中使用COMMIT的。为什么这么说呢,因为STRCMTCTL需要在OPEN File之前就执行,不用USROPN的话程序自动在第一条C行就自动Open File了,自然在执行时就会出错了。所以要想在RPG中使用COMMIT CONTROL则必须声明USROPN,并且先STRCMTCTL,后OPEN File。
2. ENDCMTCTL命令使用的位置。经多次测试,ENDCMTCTL必须在CLOSE File之后,否则程序在执行到ENDCMTCTL时是会报错的!!!错误如下图
3. 在ENDCMTCTL之前必须要有COMMIT或者ROLBK,否则会change pending。错误如下图:
RB表示rollback
CM表示commit

期间遇到的两个ERROR
CPF3426
这个错误是因为没有STRCMTCTL就开始COMMIT/ROLBK了。
CPF8355ENDCMTCTL not allowed. Pending changes active.
遇到这个是因为ENDCMTCTL的位置放错了,放在了OPEN之前了。

另外要注意的几个问题:
1.COMMIT CONTROL要操作的File必须建立Journal,相关命令CRTJRNRCV,CTRJRN,STRJRNPF
2.RPG中使用QCMDEXC API。。。其实这个可以直接用CALL的,但用CALLP的话显得高深些。。嘎嘎
3.测试中用的一个很好的命令WRKJOB OPTION(*CMTCTL),用来查看当前COMMIT CONTROL的状态。。。
4.关于COMMIT CONTROL,另外有一个帖子说的也很好
Link:
内容如下:
数据库文件是AS/400中类型为*FILE的Object;它们既可以是PF又可以是LF,既可以是外部描述,又可以是程序描述。 
访问数据库文件时使用落实控制(COMMIT/ROLBK),可以确保对数据库文件操作的以下两个结果之一: 
1、全部数据库文件操作都是成功的(落实操作); 
2、全部数据库文件操作都是无效的(取消操作). 
用这种方法,从而保证了数据库文件的完整性;另外,可以把一组操作当作一个单元来处理。 

使用落实控制,要做: 

在AS/400上: 
1、使用落实控制的准备:用CL命令CRTJRN(生成日志)、CRTJRNRCV(生成日志接收器)和STRJRNPF(日志物理文件). 
2、通知AS/400启动和结束落实控制的时间:用CL命令STRCMTCTL(启动落实控制)和ENDCMTCTL(结束落实控制). 
   ●落实控制琐: 
   在STRCMTCTL命令中,要注意指定一个上锁级别,LCKLVL(*ALL),LCKLVL(*CHG)或LCKLVL(*CS),当你的程序在落实控制下操作,并且对一个文件的记录已在落实控制下进行了I/O(输入/输出)处理,记录由落实控制加锁。 
   ●落实控制范围: 
   当用STRCMTCTL命令启动落实控制时,系统建立一个落实定义。落实定义包括作业中落实控制下修改的资料信息; 
落实定义只适用于发出STRCMTCTL命令之后的作业并且在发出ENDCMTCTL命令结束。 
   落实定义范围指出了作业中哪些程序要使用落实控制,落实定义范围在活动组级或作业级。 
   缺省的落实定义范围是发出STRCMTCTL命令的程序所在的活动组,也就是活动组级。只在这个活动组中运行的程序 
才能使用落实定义。 
   OPM程序将使用*DFTACTGRP落实定义;ILE程序用与之有关的活动组。 
   你可以在STRCMTCTL命令的落实范围参数CMTSCOPE上指定落实定义的范围。 
在RPG程序中: 
1、在要做落实控制文件的文件描述规范表上指出落实控制(COMMIT). 
2、用COMMIT落实操作码实施对在落实控制下数据库文件的一组修改,或者用ROLBK取消操作码对在落实控制下 
   数据库文件的一组修改。 

★注:落实控制只适用于数据库文件。 

[举例] 

▲<例1>;这个例子解释了在落实控制下程序所用的规范表和CL命令: 

※要准备使用落实控制,发出下列CL命令: 
1、CRTJRNRCV JRNRCV(RECEIVER) 
这个命令生成一个名为REVEIVER的日志接收器. 
2、CRTJRN JRN(JOURNAL) JRNRCV(RECEIVER) 
这个命令生成一个名为JOURNAL的日志,并连接名为RECEIVER的日志接收器. 
3、STRJRNPF FILE(MASTER TRANS) JRN(JOURNAL) 
这个命令把文件MASTER和TRANS的日志项记到日志JOURNAL中. 

※在程序中,为文件MASTER和TRANS指出COMMIT. 
------------------------------------------------------------------------------ 
FMASTER    UF   E       K       DISK         COMMIT 
FTRANS     UF   E       K       DISK         COMMIT 
F* 

C             : 
C             : 
C* 
C*  使用COMMIT操作,如果成功,做完整的一组操作;如果不成功,撤消所有修改. 
C* 
C                  UPDATE       MAST_REC                 90 
C                  UPDATE       TRAN_REC                 91 
C                  IF           *IN90 OR *IN91 
C                  ROLBK 
C                  ELSE 
C                  COMMIT 
C                  ENDIF 
----------------------------------------------------------------------------- 

※要在落实控制下操作程序,发出命令: 
1、STRCMTCTL LCKLVL(*ALL) 
这个命令启动带有最高级锁定的落实控制. 
2、CALL REVIST 
这个命令调用REVIST命令. 
3、ENDCMTCTL 
这个命令结束落实控制,并产生一个隐含的ROLL BACK操作. 

▲<例2>;:有条件的落实控制例子: 
   可以编写一个程序来控制打开一个运行时做落实控制的文件。通过完成有条件落实控制,可不用写出 
两套相同的程序:一套在落实控制下执行,另一套不在落实控制下执行。 
   COMMIT键字有一个可选参数,它允许你指定有条件的落实控制。在这个文件的文件描述规范表的键字 
区输入COMMIT键字。ILE RPG/400编译程序定义一个1个字节的与参数中规定的同名字符型字段;如果参数 
为1,文件就在落实控制下运行。 
   COMMIT键字参数必须在文件打开之前设置。可以在调用程序时传递一个值来设置,也可以在程序中直接设为"1"。 
   对于共享式打开,如果文件已经打开了,即使COMMIT键字参数设为1也没有作用。 

-------------------------------------------------------------------------------- 
FMASTER    UF   E       K       DISK         COMMIT(COMMITFLAG) 
FTRANS     UF   E       K       DISK         COMMIT(COMMITFLAG) 


C*  如果COMMITFLAG='1',文件在落实控制下打开,否则不是. 
C   *ENTRY        PLIST 
C                 PARM                          COMMITFLAG 
C                 : 
C                 : 
c* 
C*  使用COMMIT操作,如果成功,做完整的一组操作;如果不成功,撤消所有修改; 
C*  仅可在文件是在落实控制打开时,才能用COMMIT和ROLBK操作(即COMMITFLAG='1'). 
C* 
C                  UPDATE       MAST_REC                 90 
C                  UPDATE       TRAN_REC                 91 
C                  IF           COMMITFLAG='1' 
C                  IF           *IN90 OR *IN91 
C                  ROLBK 
C                  ELSE 
C                  COMMIT 
C                  ENDIF 
C                  ENDIF 
--------------------------------------------------------------------------------- 

最后,提提程序周期中的落实控制: 
   落实控制是给全过程文件用的,对主文件和次文件不使用落实控制。它的输入输出是在程序员的控制下,是由RPG 
程序周期控制,原因如下: 
●在程序中不能为最后总计输出发出一个COMMIT操作; 
●周期内的程序从一个上锁记录条件中恢复是困难的; 
●级别指示器不能由ROLBK操作更新设置; 
●一个ROLBK操作以后,处理匹配记录可能产生一个顺序错误。
1


阅读(3389) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~