zoukankan      html  css  js  c++  java
  • ABAP-DB LUW显式与隐式提交

    转载:https://www.cnblogs.com/liaojunbo/archive/2011/07/11/2103491.html

       https://blog.csdn.net/lalaoye/article/details/95622149

    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.

  • 相关阅读:
    线程池的扩展 beforeExecute() afterExecute() terminaerd()
    信号量semaphore 读写锁ReadWriteLock 倒计时器CountDownLatch 循环栅栏 CyclicBarrier 线程阻塞工具类LockSupport
    ReenTrantLock可重入锁 和synchronized 内部所锁的
    integer.valueof和integer.parseint
    守护线程
    notify wait sleep join yield yield
    Thread.stop()不要随意调用
    iterate使用了parallel() 反而消耗了更多的时间
    Stream 分支/合并 框架的实际例子
    区分Collection、Collector和collect Collectors类的静态工厂方法
  • 原文地址:https://www.cnblogs.com/ricoo/p/15480902.html
Copyright © 2011-2022 走看看