隐式提交的引申之 DBSAPLUW

作者:斌将军 约 11 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, Data Engineering, SD, 开发, 数据工程, 销售分销
隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

\--

**1**

**写在前面**

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

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

聊聊更新表时的隐式提交

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

](https://mp.weixin.qq.com/s?__biz=Mzg5OTg3ODg2MQ==&mid=2247485598&idx=1&sn=77ffb1a17f4d983ee3c12c7e924ae77d&chksm=c04dd23cf73a5b2aff9900d384a20811a571d77215ddba7408529af91ed1a1cf56055790217d&scene=21#wechat_redirect)

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

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

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

在创建销售订单增强中,当因为错误需要拦截单据创建时,需要用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**

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

**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中的一系列操作更新到数据库(最右侧,代表最终数据),以此来保证数据库数据的一致性。

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

** 代码举例: **

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**

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

**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扣的钱就不翼而飞了。

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

为了防止以上情况出现,通过SAP LUW概念,将①②③④个DB LUW捆绑成一个SAP LUW,在最后一步中提交,保证4个DB

LUW要么同时成功,要么同时失败,维护业务数据的一致性。

那如何绑定呢?

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

**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实现**

创建更新函数

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

** 更新模式: **

• 立即开始:代表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中记录

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

**4**

**结语**

隐式提交的引申之 DBSAPLUW - 封面图
隐式提交的引申之 DBSAPLUW - 封面图

以上就是关于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

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

斌将军

关于作者:斌将军

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「隐式提交的引申之DBSAPLUW.md」整理生成,仅用于内部技术分享与学习交流。