隐式提交的引申之DB/SAP LUW

--

1

写在前面

51a3603e46180b7152ac2e2c9dec0a61.png

之前发表过《聊聊更新表时的隐式提交》一文,向大家介绍隐式提交,对于数据库操作的作用

聊聊更新表时的隐式提交

斌将军,公众号:斌将军聊聊更新表时的隐式提交

有粉丝看过后,提出了自己的疑问:

0d7ad2bb86a8bab5aa4e31d0c55a6640.png

首先解释一下,该粉丝大致的问题和代码含义为:

在创建销售订单增强中,当因为错误需要拦截单据创建时,需要用commit work记录日志数据到自建表。而由于使用了commit work,导致更新自建表的同时,将生成单据的事务也提交,导致拦截失败,单据一同被创建出来。

最终采用了在增强中调用CALL...STARTING NEW TASK 方式,将更新自建表以及commit work放在函数中,这样自建表更新成功,单据也没有受到CALL...STARTING NEW TASK 中commit work的影响,成功被拦截了。

所以对CALL...STARTING NEW TASK执行后,对主程序进行隐式提交有疑问,隐式提交就不会将单据创建出来吗?

正好借此机会,解释这位粉丝疑问的同时,向大家介绍DB LUW和SAP LUW。

2

DB LUW

75be65da6928eb48687951747791d28f.png

2.1

什么是DB LUW

DB LUW(Database Logical Unit of Work):又称数据库逻辑单元。为了保证一系列数据库操作,要么同时成功提交,要么同时失败回滚,就引入了DB LUW,DB LUW 是数据库管理系统(DBMS)层面上的一个概念。

如下图:

数据库从左侧开始(代表一个DB LUW开始),经过INSERT、UPDATE、DELETE多次操作,如果其中任何一项操作出现问题,则对DB LUW开始以来的所有操作进行回滚,使数据库回滚到最左侧(最左侧,代表初始数据)。如果没有错误,执行到commit,则将这一个DB LUW中的一系列操作更新到数据库(最右侧,代表最终数据),以此来保证数据库数据的一致性。

8a2f1e0130a982d7c221afce8221426d.png

代码举例:

DB LUW,将多个数据库操作视为一组,即一个逻辑单元。如果代码中的1、2、3项操作全部成功,则COMMIT后表中有1条数据(1001);如果其中出现错误,发生回滚,则表中没有一条数据。

"--------------------@斌将军--------------------
DATA:lt_dbluw TYPE TABLE OF ztluw01,
     ls_dbluw TYPE ztluw01.


CLEAR:ls_dbluw.
ls_dbluw-werks = '1001'.
ls_dbluw-werks = '1002'.
APPEND ls_dbluw TO lt_dbluw.


"-----DB LUW 开始-----
"1、插入
INSERT ztluw01 FROM TABLE lt_dbluw.


"2、更新
UPDATE ztluw01 SET werks = '1003' WHERE werks = '1002'.
*DATA(lv_error) = 1 / 0."发生错误
IF sy-subrc NE 0.
  ROLLBACK WORK.
ENDIF.


"3、删除
DELETE FROM ztluw01 WHERE werks = '1003'.
IF sy-subrc NE 0.
  ROLLBACK WORK.
ENDIF.


"全部提交
COMMIT WORK.
"-----DB LUW 结束-----
"--------------------@斌将军--------------------

2.2

DB LUW的提交和回滚

针对DB LUW的提交操作,SAP有显式和隐式两种提交方式:

显式提交:通常为我们熟知的COMMIT WORK,以及通过函数DB_COMMIT等实现的提交操作

隐式提交:即文章《聊聊更新表时的隐式提交》一文中向大家介绍的提交方式。所以,隐式提交是针对DB LUW的提交方式。

相对应也有显式回滚和隐式回滚,道理一样,不再赘述。

2.3

DB LUW的生命周期

一个DB LUW伴随上一次提交或者回滚之后自动产生,当再次遇到提交或回滚时结束,完成一个DB LUW的活动历程。其中的提交和回滚包含显式和隐式,此概念对于理解下文至关重要。

3

SAP LUW

45b25e4513b39991f194f18cfe5b0477.png

3.1

什么是SAP LUW

SAP LUW(SAP Logical Unit of Work):又称SAP逻辑单元。指的是,在SAP系统中执行的一系列业务逻辑操作,这些操作可能涉及到多个DB LUW操作,即一个SAP LUW 可能会包含多个DB LUW。

为了能保证这一系列业务操作中的所有DB LUW全部成功或者全部失败,就引入了SAP LUW,SAP LUW 是SAP应用程序层面上的一个概念。

在SAP中,事务代码处理往往会涉及到多个业务逻辑操作,每个操作可能包含一个或多个数据库操作。

如图举例说明:

例如:当A进银行给B转账时,系统需要①查询A账户余额,②A账户扣款,③B账户打款,④保存结束。

如上文所说,当每一次屏幕调用,会触发隐式提交,则该DB LUW就执行完毕。如果③过程给B打款中出现失败,则只能从B2回滚到B1结束,而不能回滚到①过程,那么②过程中A扣的钱就不翼而飞了。

4f952e134a9a80529889b66d38e991ff.png

为了防止以上情况出现,通过SAP LUW概念,将①②③④个DB LUW捆绑成一个SAP LUW,在最后一步中提交,保证4个DB LUW要么同时成功,要么同时失败,维护业务数据的一致性。

那如何绑定呢?

b466faf98261b84e1ad405adb6b8e2ab.png

3.2

实现SAP LUW

根据SAP官方解释,通常有两种办法实现,

3.2.1

使用更新功能函数进行捆绑

使用函数的更新模式,即CALL...IN UPDATE TASK,将主程序的数据库语句放入更新函数中。使用 IN UPDATE TASK 调用函数模块时,该模块及其函数参数将作为日志条目存储在名为 VBLOG 的特殊数据库表中。

当程序遇到 COMMIT WORK 语句时,执行函数模块。如果发生逻辑错误,程序可以使用 ROLLBACK WORK 语句终止更新,则函数模块不执行,并从表VBLOG中删除日志条目。

另外也可以通过SET UPDATE TASK LOCAL设置为本地更新提交。这种方式不会将更新记录写入数据库,而是放在内存中,提交和回滚触发的方式同理。

3.2.2

使用子例程捆绑

使用PERFORM subr ON { {COMMIT [LEVEL idx]} | ROLLBACK }调用子例程。同理,在系统到达下一个 COMMIT WORK 语句时执行。其中LEVEL可设置优先级,数值越小,优先级越高

3.2.3

两者的区别

1、PERFORM...ON COMMIT 相对于CALL FUNCTION...IN UPDATE TASK具有更好的性能,因为更新数据不必写入额外的表,从而减少了数据库访问。

2、缺点是不能在PERFORM…ON COMMIT中传递参数,要使用全局变量和ABAP内存传递,使用此方法传递数据时,存在相当大的数据不一致的危险。

3.3

代码验证DB 和 SAP LUW区别

3.3.1

单纯DB LUW实现

执行隐式提交时,第一条数据已经插入成功。由于中间隐式提交,所以最终即使回滚,第一次插入的数据仍然存在。

"--------------------@斌将军--------------------
CLEAR:ls_dbluw.
ls_dbluw-werks = '1001'.


"-----DB LUW 开始-----
"1、插入
INSERT ztluw01 FROM ls_dbluw.
"模拟业务操作过程中的隐式提交
CALL FUNCTION 'ZLUW_01' STARTING NEW TASK 'TASK'."空逻辑函数
"-----DB LUW 结束-----


CLEAR:ls_dbluw.
ls_dbluw-werks = '1002'.
"-----DB LUW 开始-----
"2、插入
INSERT ztluw01 FROM ls_dbluw.
"模拟失败,导致回滚
ROLLBACK WORK.
"-----DB LUW 结束-----
"--------------------@斌将军--------------------

3.3.2

SAP LUW实现

创建更新函数

89e5b76a8b05ccf75e98315ae7b46aca.png

更新模式:

  • 立即开始:代表V1方式,设置函数为高优先级V1并运行在同一SAP LUW中。更新出错后,可以在SM13里重新执行

  • 立即启动(不可更新):代表V1方式,设置函数为高优先级V1并运行在同一SAP LUW中。出错后不可以在SM13里重新执行

  • 启动已延迟:代表V2方式,设置函数为低优先级V2并运行在自己的更新事务中。延迟的更新主要用于不紧急的数据库更改(例如统计更新)。V1方式更新完成后触发。出错后更新函数可以重启

  • 集中运行:代表V2方式,将此更新函数设置为低优先级V2并运行在自己的更新事务中。需使用Collective(RSM13005)程序手动或JOB方式执行

V1与V2区别:

  • V1优先级高于V2,V2依赖于V1,适合执行需要在V1完成后进行的操作

  • V1更新使用V1进程处理,V1进程名字一般为UPD,V1进程绑定独立的数据库进程。在V1进程中调度的更新函数如果更新失败,回滚,不再进行V2操作。成功则提交更改到数据库,同时删除所有的SAP锁

  • V2更新使用V2进程处理,如果没有配置V2进程则共用V1进程,V2进程名字为UP2,V2更新在独立DB LUW中,V2更新回滚后不会影响到V1更新提交的数据,由于V1更新结束后会删除SAP的锁,所以V2更新是在没有逻辑锁的情况下进行的,V2更新出错后可以在SM13中重新执行

  • V1 的执行模式可以为异步、同步或本地;V2只能为异步执行

如下代码:

由于使用了更新函数,即使遇到隐式提交,也不更新。

最终如果成功COMMIT,则表中有两条数据;如果失败ROLLBACK,则表中没有一条数据。

"--------------------@斌将军--------------------
"1、插入
*INSERT ztluw01 FROM ls_dbluw.
"将更新操作放在update函数中执行
CALL FUNCTION 'ZLUW_02' IN UPDATE TASK.


"模拟业务操作过程中的隐式提交
CALL FUNCTION 'ZLUW_01' STARTING NEW TASK 'TASK'.


CLEAR:ls_dbluw.
ls_dbluw-werks = '1002'.
"-----DB LUW 开始-----
"2、插入
INSERT ztluw01 FROM ls_dbluw.
"模拟失败,导致回滚
"COMMIT WORK.
ROLLBACK WORK.
"-----DB LUW 结束-----
"--------------------@斌将军--------------------

更新函数代码

"--------------------@斌将军--------------------
FUNCTION ZLUW_02.
*"-----------------------------------------------------
*"*"更新函数模块:
*"
*"*"本地接口:
*"-----------------------------------------------------


DATA:lt_dbluw TYPE TABLE OF ztluw01,
     ls_dbluw TYPE ztluw01.


CLEAR:ls_dbluw.
ls_dbluw-werks = '1001'.
"1、插入
INSERT ztluw01 FROM ls_dbluw.


ENDFUNCTION.
"--------------------@斌将军--------------------

因此可以证实,更新函数,遇到隐式提交不会运行,遇到显式提交才会。以此来保证一系列数据库操作的同时成功或失败,而无惧切换屏幕等方式引起的隐式提交。

当更新失败,会在SM13中记录

8ad553c8721ef7b255639ecf848577d1.png

4

结语

0f02d75b550f0e8477eb72daa2671323.png

以上就是关于DB LUW和SAP LUW的介绍。回到开头,在系统创建销售订单时,将其一系列操作封装为SAP LUW,因此在增强中写commit work将会更新之前的一系列数据库操作,订单创建成功。而使用隐式提交,对SAP LUW不起作用,故订单没有创建成功。

本篇文章,参考以下文档,让我获益良多,非常感谢。

https://help.sap.com/docs/SAP_NETWEAVER_701/6da3d9466c4b1014a5a2e370bd8c5dc8/417af4bfa79e11d1950f0000e82de14a.html?locale=en-US

https://www.cnblogs.com/ricoo/p/15481087.html

—— 希望本篇文章对您有所帮助 ——

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值