ABAP:关于隐式与显式的DB Commit

转自http://blog.163.com/[email protected]/blog/static/1394892972011611111559962/#userconsent#
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也是类似)

*&———————————————————————* 
*& Report  ZTEST_COMMIT_1 
*& 
*&———————————————————————* 
*& Commit 
*&  DB Commit & SAP Commit 
*&———————————————————————*

REPORT ZTEST_COMMIT_1 NO STANDARD PAGE HEADING.

*— Data & Types 
DATA: 
gs_table1 type ZOFFERING_SOLUTI, 
gs_table2 type ZOFFERING_SOLUTI, 
gt_table type TABLE OF ZOFFERING_SOLUTI.

START-OF-SELECTION.

clear:gs_table1,gs_table2.

*1. Modify the record 1 
*1-1. Retrieve the data from table 
clear:gs_table1. 
SELECT single * from ZOFFERING_SOLUTI 
into gs_table1 
where SOLUTION_ID = ‘ZTEST_01′ AND 
land  = ‘DE’. 
*1-2. Modify the description 
gs_table1-text = ‘ZTEST_01 From Program ZTEST_COMMIT_1′. 
*1-3. Using Update Subroutine 
PERFORM frm_upd_table ON COMMIT.

*2. Modify the record 2 
*2-1. Retrieve the data from table 
clear:gs_table2. 
SELECT single * from ZOFFERING_SOLUTI 
into gs_table2 
where SOLUTION_ID = ‘ZTEST_02′ AND 
land  = ‘DE’. 
*2-2. Modify the description 
gs_table2-text = ‘ZTEST_02 From Program ZTEST_COMMIT_1′. 
*2-3. Using Update Subroutine 
PERFORM frm_upd_table ON COMMIT.

IF 1 = 1. 
“    ”A type: No Update the DB(Interrupt the program) 
“    MESSAGE ’Msg A will terminate the Execution of DB-Update’ type ’A’. 
“    ”X type: No Update the DB(Interrupt the program) 
“    MESSAGE ’Msg X will terminate the Execution of DB-Update’ type ’X’. 
“    ”E type: No Update the DB(Interrupt the program) 
“    MESSAGE ’Msg E will terminate the Execution of DB-Update’ type ’E’. 
“    ”S type: Update the DB(Not Interrupt the program) 
“    MESSAGE ’Msg S will not terminate the Execution of DB-Update’ type ’S’. 
“    ”I type: Update the DB(Interrupt the program, but will go back then commit work!) 
“    MESSAGE ’Msg I will not terminate the Execution of DB-Update’ type ’I’.

“Leave to program(Will not execute the UPDATE-REQUEST by perfrom-on-commit) 
Submit ZTEST_ALV_1 . 
ENDIF.

*3. DB Commit 
COMMIT WORK. 
IF sy-subrc = 0. 
MESSAGE ‘Your Program executed Successfully!’ TYPE ‘S’. 
ENDIF.

*&———————————————————————* 
*&      Form  FRM_UPD_TABLE 
*&———————————————————————* 
*       Using Update Subroutine to Update the Table 
*———————————————————————-* 
FORM FRM_UPD_TABLE .

* Modify the DB Table using Work area 1 
IF gs_table1 is not INITIAL. 
MODIFY ZOFFERING_SOLUTI from gs_table1. 
IF sy-subrc <> 0. 
MESSAGE ‘Your Modify is failed!’ type ‘A’. 
ENDIF. 
ENDIF.

* Modify the DB Table using Work area 2 
IF gs_table2 is not INITIAL. 
MODIFY ZOFFERING_SOLUTI from gs_table2. 
IF sy-subrc <> 0. 
MESSAGE ‘Your Modify is failed!’ type ‘A’. 
ENDIF. 
ENDIF.

ENDFORM. “ FRM_UPD_TABLE

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

其实这也是On commit或update FM中最基本的。

时间: 2024-10-19 21:36:03

ABAP:关于隐式与显式的DB Commit的相关文章

android之intent显式,显式学习

intent,意图 当从一个Activity到另一个Activity时调用,这里重点学习显式,隐式的使用 使用语句上的区别: 隐式意图:                 显式意图: setAction                                            跳转到其他应用:setClassName setData 跳转到自己应用:setClass addCategory(当为DEFAULT时可无) 一.无参时的显式.隐式举例 显式-到自己应用(最简单情况): /*

Oracle-35-隐式游标&amp;显式游标

一.游标作用(或定义) 1.PL/SQL提供游标机制处理多行记录结果集: 2.游标类似于指针,使应用程序一次可以处理其中的一行记录,比如将游标放入一个for循环中,每循环一次就处理一行记录,那么循环n次就可以处理n行记录: 3.Oracle中,可以分为显式游标和隐式游标两种,比如select*fromstudent就是用隐式游标进行遍历student表,然后将查询结果展示: 4.在平常在进行SELECT查询.DML操作Oracle都会自动创建声明"隐式游标"来处理结果数据: 6.如果需

Windows提供了两种将DLL映像到进程地址空间的方法(隐式和显式)

调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同.Windows提供了两种将DLL映像到进程地址空间的方法: 1. 隐式的加载时链接 这种方法需要DLL工程经编译产生的LIB文件,此文件中包含了DLL允许应用程序调用的所有函数的列表,当链接器发现应用程序调用了LIB文件列出的某个函数,就会在应用程序的可执行文件的文件映像中加入一些信息,这些信息指出了包含这个函数的DLL文件的名字.当这个应用程序运行时,也就是它的可执行文件

c# implicit explicit关键字(隐式和显式数据类型转换)

implicit关键字用于声明隐式的用户定义类型转换运算符.(explicit反之)explicit则用于显示转换用户自定义类型.static implicit operator target_type ( source_type identifier ){......}隐式转换可以通过消除不必要的类型转换来提高源代码的可读性.但是,因为可以在未指定的情况下发生隐式转换,因此必须注意防止令人不愉快的后果. 一般情况下,隐式转换运算符应当从不引发异常并且从不丢失信息,以便可以在不知晓的情况下安全使

C#接口的隐式和显式实现

1:当类实现一个接口是,通常使用隐式接口实现,这样可以方便的访问接口方法和类自身具有的方法和属性 2:当类实现多个接口且接口包含相同的方法签名,此时使用显式接口实现.(标示出哪个接口属于哪个方法) 3:隐式接口实现:类和接口都可以访问接口中的方法 4:显式接口实现:只能通过接口访问. 举例如下: ①隐式 1 interface Animal 2 3 { 4 5 void Speak(); 6 7 } 8 9 class Dog:Animal 10 { 11 public void Speak()

安卓突击:隐式、显式Intent

android当中显式intent和隐式intent的区别 定义: Intent定义:Intent是一种在不同组件之间传递的请求消息,是应用程序发出的请求和意图.作为一个完整的消息传递机制,Intent不仅需要发送端,还需要接收端. 显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent. 隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent. 说明:Android系统使用IntentFilter 来寻找与隐式Intent

AngularJS中的隐式和显式依赖注入

在之前学习AngularJS的过程中,都是用到了显式依赖注入,比如: <script type="text/javascript"> angular.module('app', []) .controller('Controller1', function($scope) { $scope.something = 'hello world'; }); </script> 依赖注入$scope.这么写有个弊端,在发布的时候,往往要压缩JavaScript代码,压缩

IOS动画隐式,显式,翻页

//  ViewController.m //  IOS动画0817 // //  Created by 张艳锋 on 15/8/17. //  Copyright (c) 2015年 张艳锋. All rights reserved. // #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *imageview; - (IBA

activity的隐式和显式启动

显式Intent(Explicit intent):通过指定Intent组件名称来实现的,它一般用在知道目标组件名称的前提下,一般是在相同的应用程序内部实现的. 隐式Intent(Implicit intent):通过Intent Filter来实现的,它一般用在没有明确指出目标组件名称的前提下,一般是用于在不同应用程序之间. 显式: Intent intent=new Intent(MainActivity.this,SettingActivity.class); startActivity(