结合实例快速理解SAP中SAP/DB LUW 机制

首先LUW(Logic Unit of Work)是什么意思,从字面意思理解逻辑单元,可以把一系列的数据库操作统一提交和回滚,从而来保证数据库更新的一致性。

在SAP中,由于业务处理复杂,涉及到的DB也很多,业务是分好几步去完成的,所以需要和数据库多次交互来更新数据,但是每次DB LUW并不受我们控制,和数据库的交互都会更新数据进去,业务最后一步出错,那么这个业务不算是完整的,需要把之前存进数据库的业务数据全部回滚,所以带来了很多的不便。所以SAP引入了SAP LUW来控制这个和DB交互的操作,统一去提交DB和回滚DB。

因此,我们完整的流程变成了 SAP LUW(多个 DB  LUW 集合) -> 提交(最后一次DB LUW)-> DB,最终完成更新。

那么我们怎么把这些和DB的交互都放入一个"集合",也就是所谓的SAP LUW,然后我们又应该用什么样的方法来触发”提交"的操作呢?我们结合实例的几个CASE来看。

CASE1: 表一插入一条数据,表二插入两条数据,其中一条使用SAP LUW,另一条不使用,表三使用submit调用外部程序更新表三,在主程序中使用回滚操作ROLLBACK WORK,在外部程序使用commit work。所以结果是什么?最终会更新几条数据进去?

REPORT ZTEST_LUW_GJX.

DATA: gt_ztestluw01 TYPE STANDARD TABLE OF ztestluw01 WITH HEADER LINE,
      gt_ztestluw02 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE,
      gt_ztestluw03 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE.

DELETE FROM ztestluw01 .
DELETE FROM ztestluw02 .
DELETE FROM ztestluw03 .

COMMIT WORK.
BREAK-POINT .

gt_ztestluw01-luwid = '00001'.
gt_ztestluw01-luwty = 'sap_luw'.
MODIFY ztestluw01 FROM gt_ztestluw01 .

gt_ztestluw02-luwid = '00001'.
gt_ztestluw02-luwty = 'sap_luw'.
APPEND gt_ztestluw02 .

CALL FUNCTION 'ZTEST_INSERT_LUW' IN UPDATE TASK
  TABLES
    it_dbtable2       = gt_ztestluw02
          .

SUBMIT ZTEST_LUW_GJX01 AND RETURN .

gt_ztestluw02-luwid = '00002'.
gt_ztestluw02-luwty = 'sap_luw'.
MODIFY ztestluw02 FROM gt_ztestluw02 .
ROLLBACK WORK .

BREAK-POINT .
------------------------------------------------------------------------
FUNCTION ZTEST_INSERT_LUW.
*"----------------------------------------------------------------------
*"*"Update Function Module:
*"
*"*"Local Interface:
*"  TABLES
*"      IT_DBTABLE1 STRUCTURE  ZTESTLUW01 OPTIONAL
*"      IT_DBTABLE2 STRUCTURE  ZTESTLUW02 OPTIONAL
*"----------------------------------------------------------------------

 MODIFY ztestluw01 FROM TABLE IT_DBTABLE1 .

 MODIFY ztestluw02 FROM TABLE IT_DBTABLE2 .


ENDFUNCTION.
*&---------------------------------------------------------------------*
*& Report ZTEST_LUW_GJX01
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZTEST_LUW_GJX01.
DATA: gt_ztestluw01 TYPE STANDARD TABLE OF ztestluw01 WITH HEADER LINE,
      gt_ztestluw02 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE,
      gt_ztestluw03 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE.

gt_ztestluw03-luwid = '00001'.
gt_ztestluw03-luwty = 'sap_luw'.
MODIFY ztestluw03 FROM gt_ztestluw03 .

COMMIT WORK .

结果是两条,表一,表三各有一条,表二没有。因为submit语句会新开一个DB LUW,但是它和主程序是处于同一个 external session的,只是在不同的internal session里面,而只有表二使用了SAP LUW来延迟更新,所以碰到commit work,其余的DB LUW就立即提交到了DB。

CASE2: 我们把上面的代码稍微变换一下, 把表一的更新也加入SAP LUW会发生什么?

gt_ztestluw01-luwid = '00001'.
gt_ztestluw01-luwty = 'sap_luw'.
APPEND gt_ztestluw01.
CALL FUNCTION 'ZTEST_INSERT_LUW' IN UPDATE TASK
  TABLES
    it_dbtable1       = gt_ztestluw01
         .

没错,就只有表三会更新一条数据。那么至此我们可以得出结论

  • 1. 对于DB LUW来说只要处于同一个external session时,碰到commit work 或者 rollback work就结束当前的DB LUW,开启新的DB LUW.
  • 2.对于SAP LUW来说,不同的internal session里面各个SAP LUW是互不影响的,在各自的internal session里面碰到commit work 或者 rollback work就结束当前的SAP LUW,开启新的SAP LUW。

CASE3: 继续对上面的代码变化,去掉report:ZTEST_LUW_GJX01里面的commit work,去掉主程序的所有显示提交。

*&---------------------------------------------------------------------*
*& Report ZTEST_LUW_GJX
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZTEST_LUW_GJX.

DATA: gt_ztestluw01 TYPE STANDARD TABLE OF ztestluw01 WITH HEADER LINE,
      gt_ztestluw02 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE,
      gt_ztestluw03 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE.

DELETE FROM ztestluw01 .
DELETE FROM ztestluw02 .
DELETE FROM ztestluw03 .

COMMIT WORK.
BREAK-POINT .

gt_ztestluw01-luwid = '00001'.
gt_ztestluw01-luwty = 'sap_luw'.
APPEND gt_ztestluw01.
MODIFY ztestluw01 FROM gt_ztestluw01 .
*CALL FUNCTION 'ZTEST_INSERT_LUW' IN UPDATE TASK
*  TABLES
*    it_dbtable1       = gt_ztestluw01
*          .

gt_ztestluw02-luwid = '00001'.
gt_ztestluw02-luwty = 'sap_luw'.
APPEND gt_ztestluw02 .

CALL FUNCTION 'ZTEST_INSERT_LUW' IN UPDATE TASK
  TABLES
    it_dbtable2       = gt_ztestluw02
          .

SUBMIT ZTEST_LUW_GJX01 AND RETURN .

gt_ztestluw02-luwid = '00002'.
gt_ztestluw02-luwty = 'sap_luw'.
MODIFY ztestluw02 FROM gt_ztestluw02 .

BREAK-POINT .
*&---------------------------------------------------------------------*
*& Report ZTEST_LUW_GJX01
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZTEST_LUW_GJX01.
DATA: gt_ztestluw01 TYPE STANDARD TABLE OF ztestluw01 WITH HEADER LINE,
      gt_ztestluw02 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE,
      gt_ztestluw03 TYPE STANDARD TABLE OF ztestluw02 WITH HEADER LINE.

gt_ztestluw03-luwid = '00001'.
gt_ztestluw03-luwty = 'sap_luw'.
MODIFY ztestluw03 FROM gt_ztestluw03 .

结果是表一,表二,表三各有一条数据,我们给表二加了两条数据为什么只有一条数据成功更新到DB呢?我们把表二的SAP LUW去掉,发现两条数据都更新进了DB。当在主程序最后加上rollback work的时候,所有的表都不会再有数据更新,所以不难得出结论:

  •  SAP LUW是必须有显示提交的或者显示回滚的,隐式触发不起作用。
  •  DB LUW可以由隐式触发
  •  显示的优先级大于隐式

隐式提交:

  • 对话屏幕结束时(跳转另一屏幕),一个dialog结束
  • call transaction <tcode> or SUBMIT <program> statement
  • ·同步或异步方式远程调用RFC
  • 发送dialog消息时(type: E,S,I)

隐式回滚

  • runtime error
  • dump等终端程序
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gong JX

多谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值