ABAP使用SQL直接更新数据库与使用IN UPDATE TASK的区别

打印 上一主题 下一主题

主题 571|帖子 571|积分 1713

1. 配景

刚打仗ABAP的小同伴常常会有这样的疑问,为什么不直接使用Open SQL直接更新数据库,而要把对DB的操作封装到IN UPDATE TASK中呢?
对于这个问题,比较常见的解释是,IN UPDATE TASK的方式会保证数据更新的同等性。因为,它注册了一个SAP LUW,在这个逻辑业务单位中的操作,将会一起成功/失败。
这个解释是没问题的,但可能还是稍微缺少点直观的感觉。在本篇博客中,让我们一起通过几个测试,来更深入地明确下IN UPDATE TASK的用法。
2. 测试

2.1 测试1 - Open SQL 与IN UPDATE TASK混淆使用

起首,让我们测试下,如果Open SQL 与 IN UPDATE TASK混淆使用会发生什么?
建立一个UPDATE Module的Function Module ZUPDATE_MODULE_1.

在这个函数中,我们将完成一条数据的插入。
  1. FUNCTION zupdate_module_1.
  2.   BREAK-POINT.
  3.   FINAL(ls_spfli) = VALUE spfli( carrid    = 'LH'
  4.                                  connid    = '456' ).
  5.   INSERT INTO spfli VALUES @ls_spfli.
复制代码
然后,让我们在程序ztest_luw中,使用Open SQL插入另一条数据,同时调用更新模块函数zupdate_module_1。
  1. REPORT ztest_luw.
  2. START-OF-SELECTION.
  3.   FINAL(ls_spfli) = VALUE spfli( carrid    = 'LH'
  4.                                  connid    = '123' ).
  5.   INSERT INTO spfli VALUES @ls_spfli.
  6.   CALL FUNCTION 'ZUPDATE_MODULE_1' IN UPDATE TASK.
  7.   BREAK-POINT.
  8.   COMMIT WORK.
  9.   BREAK-POINT.
复制代码
在程序中,我已经预设了断点,让我们看一下运行效果。
当执行到Commit Work后,系统会开启一个新的进程,用于执行zupdate_module_1,而在当前的dialog session中的Open SQL已经完成了数据的更新。

   这样做的效果是:当前会话进程所提交的数据库更新,与IN UPDATE TASK所提交的数据库更新,相互独立。带来的后果是,两部分数据更新也是相互独立的。
若IN UPDATE TASK更新失败,会话进程的更新并不受影响。
  整体上看,这样实际产生了两个独立的LUW,一个是会话进程中OPEN SQL带来的,另一个是IN UPDATE TASK带来的。
在SAP的尺度代码中,会出现类似的场景,但不推荐这样用。因为,这样做的条件是,开发者或业务逻辑的负责人,要清晰地知道其影响与后果,一次业务操作后,可能引发部分操作成功,部分操作失败
而在绝大多数场景中,我们最期望的效果是,程序运行可以简单直接,更新全部成功或全部失败。
2.2 测试2 - COMMIT WORK AND WAIT的效果

我们知道COMMIT WORK AND WAIT的效果是同步更新,也即触发新的更新进程,但要等到更新进程执行竣事后,会话进程才会继续。
若在测试1的场景中,使用COMMIT WORK AND WAIT替代COMMIT WORK,会有什么影响呢?
  1. START-OF-SELECTION.
  2.   FINAL(ls_spfli) = VALUE spfli( carrid    = 'LH'
  3.                                  connid    = '123' ).
  4.   INSERT INTO spfli VALUES @ls_spfli.
  5.   CALL FUNCTION 'ZGG_UPDATE_MODULE_1' IN UPDATE TASK.
  6.   BREAK-POINT.
  7.   COMMIT WORK AND WAIT. " <<-------what will happen?
  8.   BREAK-POINT.
复制代码
其运行效果如下:

可见COMMIT WORK AND WAIT的效果和COMMIT WORK的效果是类似的。COMMIT WORK AND WAIT仍会触发新的更新进程,并且独立于当前的会话进程,会话进程固然被WAIT壅闭,但会话进程中对于数据库的提交并不受影响。
2.3 测试3 - SET UPDATE TASK LOCAL 的效果

通过SET UPDATE TASK LOCAL可以让IN UPDATE TASK不启动新的更新进程,让我们测试一下,SET UPDATE TASK LOCAL在OPEN SQL与IN UPDATE TASK混用场景中的效果。
改动代码如下:
  1. START-OF-SELECTION.
  2.   FINAL(ls_spfli) = VALUE spfli( carrid    = 'LH'
  3.                                  connid    = '123' ).
  4.   INSERT INTO spfli VALUES @ls_spfli.
  5.   SET UPDATE TASK LOCAL.  "<<---set before registering
  6.   CALL FUNCTION 'ZGG_UPDATE_MODULE_1' IN UPDATE TASK.
  7.   BREAK-POINT.
  8.   COMMIT WORK AND WAIT.
  9.   BREAK-POINT.
复制代码
其运行效果如下:

可以发现,通过SET UPDATE TASK LOCAL,将会直接使用当前的会话进程完成对于IN UPDATE TASK注册函数的执行,并未触发新的更新进程。
   在此例中,通过SET UPDATE TASK LOCAL,实现了LUW的合并。
  OPEN SQL所提交的数据库更新和IN UPDATE TASK提交的数据库更新同属一个LUW,会一起成功,一起失败。
3. 总结

通过本文中的几个测试,我们可以看到IN UPDATE TASK对程序带来的影响。
   总结使用经验的话,推荐将所有的数据库更新操作,统一通过IN UPDATE TASK注册,不要在会话进程中通过OPEN SQL提交数据库的更新操作,而是将这些操作封装到IN UPDATE TASK中。
  但又有小同伴问了,若是所有的数据库更新操作都在当前的会话进程中,不也能保证数据的同等性嘛?
答案是“肯定的”。这种方式确实是保证了进程中只有一个LUW。但在实际场景中,对于数据库的操作其实是“一系列”的动作,并非简单一句INSERT或UPDATE。将这些操作封装到IN UPDATE TASK中举行异步更新,将会让终端用户的操作更加流通。
因为,当所有的输入信息和校验通过后,用户便可以竣事当前的会话进程,而不必等候所有的数据库更新竣事后才气竣事会话。
   但注意,任何事情都不是绝对的,如果一个应用程序的逻辑非常简单,数据库更新操作的数据量也很小,不使用IN UPDATE TASK,直接在会话举行中使用OPEN SQL更新数据库,也是可以的。
    要避免的场景是,在会话进程通过OPEN SQL更新数据库,与通过IN UPDATE TASK更新数据库,在同一程序中的混淆使用!
  以上,是本文对于ABAP中使用SQL直接更新数据库与使用IN UPDATE TASK的区别的一些总结,希望对你有资助!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表