IT干货网

ABAP-DB LUW显式与隐式提交

flyfish 2022年03月09日 SAP 149 0

转载:IT虾米网

   IT虾米网

   IT虾米网

1.显式的DB Commit

显式的DB Commit并没有对应的ABAP 语句来执行DB Commit,它是由平常的语句Commit Work来进行的.一个DB LUW中,我们是以该DB被打开,然后以DB Commit结束。

2.隐式的DB Commit

隐式的DB Commit更没有对应的ABAP语句来告诉系统(Okay,您给我偷偷模模做一下commit)。隐式的DB commit是由许多”未留意”的用户/系统操作所带来的附加影响,总结了一下,可以触发隐式DB Commit的操作主要有:

(1) When the system displays an SAP Screen

(2) When the system sends a dialog message(Okay: E,S, I; No:A,X)

(3) Whenever there are synchronous and asynchronous RFC calls

(4) With call transaction <tcode> or SUBMIT <program> statement

所以,从上面我当年范的错误中,也可以知道,如果我们不手动地为数据库操作语句加上commit work,当程序结束后(也就是会send msg或者selection screen等)会自动进行DB Commit;

同时,另外非常重要的一点就是,rollback只能在同一个DB LUW中进行操作,如果DB LUW被commit了,那么其将还原不了了。

同时,Debug会自动进行direct的DB LUW(注意,非update FM或perform <> on commit)的commit,所以,debug永远也就找不到答案了。

3. DB Commit与SAP LUW

正因为有了隐式的DB Commit,这时一个DB LUW结束了,同时该DB的物理锁被release了,所以,特别是在我们的Dynpro程序中我们需要定义SAP LUW,才需要了SAP Lock机制而不能依靠于DB Lock机制;

同时,我们知道,一个SAP LUW的结束是以commit work的ABAP语句为标志的,所以,这里就明白了,commit work在原理上将会带来如下的影响:

(1) 如果有打开的DB LUW,那么该DB LUW将会被结束

(2) 当前的SAP LUW将会被结束

另外,上面也已经提到,如果我们不是使用的direct的数据库更新技术,而是使用的如update FM或者perform <> On Commit这样的数据库更新技术,也就是说我们将数据库更新封装在一个SAP LUW中,这时上面的隐式的DB Commit是否会影响到这个SAP LUW中的数据库更新request呢?不会。

因为上面的隐式commit是针对DB Commit呢,而不是针对SAP Commit的。如果要执行上面SAP LUW中的数据库更新request,必须使用commit work这样的显式的DB/SAP Commit。

所以,这个时候就得注意了,特别是我们在程序中如果使用了Link program,也就是说牵涉到不同的session不同的program间的关系了,这时候,一定得保证,在前面program里的数据库更新请求是否被释放了(Commit)了,如果没有被commit,那么很遗憾,您的数据库更新就不会被执行了,这个时候虽然有隐式的DB commit,但并不起作用。

4. 测试实例

关于上面提到的那四类可以隐式的触发DB Commit的情形,以及在同一个DB LUW中的commit和rollback,我们可以创建很多自己的测试程序进行测试。

这里仅测试一下平常使用频率非常高的Update技术下的DB/SAP Commit.

该程序完成:

使用Perform <> On commit对数据库表的两条记录进行update。

分别测试了:

(1) 使用A msg:不发生隐式的DB Commit,也不会执行数据库更新request

(2) 使用X msg:不发生隐式的DB Commit,也不会执行数据库更新request

(3) 使用E msg:发生隐式的DB Commit,但不会执行数据库更新request

(4) 使用S msg:不发生隐式的DB Commit,跑到下面执行数据库更新request

(5) 使用I msg:发生隐式的DB Commit,返回后跑到下面继续、执行数据库更新request

(6) 使用Link Program:发生隐式的DB Commit,但不会执行数据库更新request(另外如leave to transaction也是类似)

 1 *&———————————————————————* 
 2 *& Report  ZTEST_COMMIT_1 
 3 *& 
 4 *&———————————————————————* 
 5 *& Commit 
 6 *&  DB Commit & SAP Commit 
 7 *&———————————————————————* 
 8  
 9 REPORT ZTEST_COMMIT_1 NO STANDARD PAGE HEADING. 
10  
11 *— Data & Types 
12 DATA: 
13 gs_table1 type ZOFFERING_SOLUTI, 
14 gs_table2 type ZOFFERING_SOLUTI, 
15 gt_table type TABLE OF ZOFFERING_SOLUTI. 
16  
17 START-OF-SELECTION. 
18  
19 clear:gs_table1,gs_table2. 
20  
21 *1. Modify the record 1 
22 *1-1. Retrieve the data from table 
23 clear:gs_table1. 
24 SELECT single * from ZOFFERING_SOLUTI 
25 into gs_table1 
26 where SOLUTION_ID = ‘ZTEST_01′ AND 
27 land  = ‘DE’. 
28 *1-2. Modify the description 
29 gs_table1-text = ‘ZTEST_01 From Program ZTEST_COMMIT_1′. 
30 *1-3. Using Update Subroutine 
31 PERFORM frm_upd_table ON COMMIT. 
32  
33 *2. Modify the record 2 
34 *2-1. Retrieve the data from table 
35 clear:gs_table2. 
36 SELECT single * from ZOFFERING_SOLUTI 
37 into gs_table2 
38 where SOLUTION_ID = ‘ZTEST_02′ AND 
39 land  = ‘DE’. 
40 *2-2. Modify the description 
41 gs_table2-text = ‘ZTEST_02 From Program ZTEST_COMMIT_1′. 
42 *2-3. Using Update Subroutine 
43 PERFORM frm_upd_table ON COMMIT. 
44  
45 IF 1 = 1. 
46 “    ”A type: No Update the DB(Interrupt the program) 
47MESSAGE ’Msg A will terminate the Execution of DB-Update’ type ’A’. 
48 “    ”X type: No Update the DB(Interrupt the program) 
49MESSAGE ’Msg X will terminate the Execution of DB-Update’ type ’X’. 
50 “    ”E type: No Update the DB(Interrupt the program) 
51MESSAGE ’Msg E will terminate the Execution of DB-Update’ type ’E’. 
52 “    ”S type: Update the DB(Not Interrupt the program) 
53MESSAGE ’Msg S will not terminate the Execution of DB-Update’ type ’S’. 
54 “    ”I type: Update the DB(Interrupt the program, but will go back then commit work!) 
55MESSAGE ’Msg I will not terminate the Execution of DB-Update’ type ’I’. 
56  
57 “Leave to program(Will not execute the UPDATE-REQUEST by perfrom-on-commit) 
58 Submit ZTEST_ALV_1 . 
59 ENDIF. 
60  
61 *3. DB Commit 
62 COMMIT WORK. 
63 IF sy-subrc = 0. 
64 MESSAGE ‘Your Program executed Successfully!’ TYPE ‘S’. 
65 ENDIF. 
66  
67 *&———————————————————————* 
68 *&      Form  FRM_UPD_TABLE 
69 *&———————————————————————* 
70 *       Using Update Subroutine to Update the Table 
71 *———————————————————————-* 
72 FORM FRM_UPD_TABLE . 
73  
74 * Modify the DB Table using Work area 1 
75 IF gs_table1 is not INITIAL. 
76 MODIFY ZOFFERING_SOLUTI from gs_table1. 
77 IF sy-subrc <> 0. 
78 MESSAGE ‘Your Modify is failed!’ type ‘A’. 
79 ENDIF. 
80 ENDIF. 
81  
82 * Modify the DB Table using Work area 2 
83 IF gs_table2 is not INITIAL. 
84 MODIFY ZOFFERING_SOLUTI from gs_table2. 
85 IF sy-subrc <> 0. 
86 MESSAGE ‘Your Modify is failed!’ type ‘A’. 
87 ENDIF. 
88 ENDIF. 
89  
90 ENDFORM. “ FRM_UPD_TABLE
View Code

另外,这里还必须说明一下:因为是on commit的执行,它并不像direct那样,做完了第一条的update后然后再去做第二条的update,它是在最后遇到commit work后才去执行,也就是说,如果不使用分别的gs_table1与gs_table2,相反例如只使用一个gs_table那么它只将更新最后一次得到的那个work area.

——————————————————————————————————————————————————————————————————————————————————————

增强里面写commit相关语句,可能会造成严重问题。同样,rollback work也不能出现在增强中

举例:在我们的MIGO操作时,首先产生物料凭证,同时去生成会计凭证。在中间书写commit语句(比如常用的增强点:MB_MIGO_BADI),可能造成生成物料凭证时,commit到了数据库,而后续凭证因为某些问题,没有产生成功,此时就造成了整体业务的不一致。

提交数据库方式:

1、显示提交。是指使用commit work或者这条语句触发的提交(包含封装这条语句的function module,如DB_commit, bapi_transaction_commit等)。

2、隐式提交。如

1、对话屏幕结束时(跳转另一屏幕)。如call screen、CALL TRANSACTION <t_code> or SUBMIT <program>.

2、同步或者异步远程调用RFC.

CALL FUNCTION func DESTINATION dest

(在DESTINATION不省略的情况下,且dest取值又不为SPACE,则函数一定要是RFC函数才能采用此方式进行远程同步调用)

CALL FUNCTION func STARTING NEW TASK DESTINATION dest taskname

异步调用时不能有IMPORTING参数;函数一定要是RFC函数才能采用异步调用;只要有STARTING NEW TASK选项,即为异步调用;如果是异步调用同一目标端的RFC函数,则可以省略DESTINATION

但RFC事务调用不会触发隐式提交:

CALL FUNCTION func IN BACKGROUND TASK DESTINATION dest

(函数一定要为RFC函数,且要通过Commit Work语句显示提交后,才会去执行,否则不会执行;如果是同一目标端的RFC函数,则可以省略DESTINATION)

3、WAIT UNTIL log_exp [UP TO sec SECONDS]语句

因为 WAIT UP 语句有提交 数据库 的作用,所以在增强里面是禁止使用 WAIT UP 语句的,可以如下:WAIT UP TO 1 SECOND.

改为:

CALL FUNCTION 'ENQUE_SLEEP'

EXPORTING

seconds = 1

EXCEPTIONS

OTHERS = 2.

4、消息输出,如打印E,I,W类型的消息
——————————————————————————————————————————————————————————————————————————————————————

RFC不会触发隐式提交:

CALL FUNCTION func IN BACKGROUND TASK DESTINATION dest

CALL FUNCTION func IN UPDATE TASK


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

ABAP-数据归档