ABAP调用BAPI时COMMIT WORK AND WAIT未按照预期同步提交问题分析

背景:

在做ABAP开发时,经常会有连续调用BAPI的需求,比如先创建销售订单,再依据销售订单创建交货单,再对交货单进行过账等类似的一连串调用,这种类似的场景往往需要前一步操作的数据完全写入数据库才能进行一下个步骤,但是数据写入底表是需要时间的,如果一些业务数据比较复杂,可能在调用下一个BAPI时会因为数据尚未写入底表而导致BAPI报出单据不存在等类似的错误消息(如果BAPI是以异步提交方式处理),这时候不同的开发者会往往有不同的处理方式,比如WAIT UP TO XXX SECONDS之类的操作,但并不推荐这么去做,因为往往会浪费一些不必要的时间,本文将结合笔者自身经验来分析这个问题,提供一些不同的解决方式,根据实际情况进行选择。


BAPI的执行原理:

大部分BAPI执行的大概过程如下:

:报表程序中调用BAPI;

②③④:BAPI内部经过一系列检查处理后,将需要更新提交的数据统一注册到更新进程LUW中;

如果BAPI本身比较规范的话,一般会有类似COMMIT_WORK以及COMMIT_WORK_AND_WAIT等类似的传入参数,那么我们最好是通过参数使其内部以同步方式提交,或者使其内部不要提交,由调用者来决定是否已同步方式提交(AND WAIT附加项决定了更新进程是否以同步模式提交);

在碰到COMMIT WORK语句后,之前注册的所有更新函数将按照顺序依次执行⑦⑧⑨⑩,并且BAPI中产生的锁会一并带到更新进程中,优先执行V1更新,V1更新执行完毕后,数据库进行提交,并且释放所有的锁,V2进程不会再有加锁的操作,V2执行完毕后,整个数据库提交过程完毕,如果更新进程中出错,则会自动触发回滚,并收到一条Dump快件;

如果是以同步提交(COMMIT WORK AND WAIT)触发更新,则程序会在更新进程执行完毕后才返回至调用程序,如果是以异步方式(COMMIT WORK)触发更新,则程序不会等待更新进程执行完毕,立即进行后续处理,这种时候如果要对该BAPI产生的单据进行下一步处理,则可能会出现单据不存在,或者锁定报错;

某些BAPI中的更新进程中甚至会有上图中的处理流程,将一部分数据处理用IN BACKGROUD TASK的方式去触发异步事务性函数(tRFC)处理,尽管这种方式已被SAP标记为过时的方式,但是仍然有一些BAPI中采用了这种方式,比如报工BAPI:BAPI_PRODORDCONF_CREATE_TT,其中针对于货物移动的处理就是采用的这种方式,使用IN BACKGROUND TASK触发的事务会立即以异步方式在独立进程中执行,所以AND WAIT不会对其生效。


更新进程的处理流程:

官方说明:

After the transaction closes, the dialog work process closes the VBHDR entry (the beginning of the update for the update request), and searches for an update server for the U1 update. This described in more detail in Update Dispatching with Load-Balancing.

The update server distributes the tasks to an update work process. This processes the V1 modules of the update request, triggers a COMMIT to the database, and releases the R/3 locks on the update request (see The SAP Lock Concept). Then the work process searches for an update server for the U2 update, if the U2 update modules exist.

These are forwarded from a U2 update server to a U2 work process that processes the U2 modules, and triggers a COMMIT on the database.

The following graphic displays this process from the view of various work processes. It also displays the time at which changes to the database are made.

官方说明:

The U1 modules are processed by transmitting the contents of the update table VBMOD and VBDATA to the application tables of the database. The changes are actually in the desired tables in the database only at the end of the database LUW in which it occurs. The SAP locks are released and, if V2 update modules exist, the V2 update is started. This is similar to the V1 update with the exception that there are no locks that have to released and no search for a process for further processing.

需要注意的是,V1更新是可选同步更新或者异步更新,根据附加项AND WAIT来决定,V2更新则永远是异步更新,COMMIT WORK AND WAIT也只会等待V1更新完毕。 


COMMIT WORK AND WAIT不生效的原因:

知道了BAPI以及更新进程的原理,那同步提交不生效的原因就变得清晰了,大概有以下几种情况:

  • BAPI没有NO_COMMIT以及COMMIT_WORK_AND_WAIT等类似的参数,直接在内部执行了COMMIT WORK语句(没有附加AND WAIT),因为内部的COMMIT WORK已经触发了更新进程的处理,所以调用程序中的COMMIT WORK AND WAIT将没有东西可触发,所以会不生效,类似的BAPI有BAPI_MATERIAL_SAVEDATA,BAPI_ENTRYSHEET_CREATE 和 BAPI_PO_RESET_RELEASE等。
  • BAPI本身提供了NO_COMMIT参数,但是调用时未传入该参数,导致BAPI内部仍然以异步方式进行了提交,故调用侧的同步提交不生效,类似的BAPI有BAPI_PO_RELEASE,CO_SE_PRODORD_OPR_CREATE等。
  • BAPI在更新进程中触发了新的异步远程更新进程,如报工BAPI:BAPI_PRODORDCONF_CREATE_TT,COMMIT WORK AND WAIT只会等到IN UPDATE TASK注册的更新进程处理完毕,并不会等待IN BACKGROUND TASK注册的更新进程。

标准BAPI事务模型规范:

BAPI 事务模型必须为用户提供明确的事务控制权。因此,如果同时调用多个 BAPI,则调用方可以自行决定何时执行 COMMIT WORK(或者,视情况而定,执行 ROLLBACK WORK)。这意味着 BAPI 本身不能(通常)执行 COMMIT WORK 命令。
以下限制适用于将多个 BAPI 合并到一个 LUW 中:

  • 如果实例是由写入 BAPI 创建、修改或删除的,则读取 BAPI 只有在发生 COMMIT WORK 时才能访问最新数据。
  • 不能在一个 LUW 中的同一实例上进行两次写入访问。例如,不能先在同一 LUW 中创建然后更改对象。但是,您可以在 LUW 中创建同一对象类型的多个实例。

尽管 SAP 提供的所有 BAPI 都应遵循此事务模型,但也有例外,并不是所有BAPI都会按照这个规范去操作,所以碰到这种情况,则需要按照实际情况去分析处理。


如何解决:

解决该问题的方式有很多种,其中最不推荐的则是WAIT UP TO XXX SECONDS的方式,尽管高版本中可以选择WAIT UP TO '0.1' SECONDS的方式,但对于一些强迫症开发者来说,多余浪费的0.01秒都是不能容忍的,所以可以有以下几种替代方式来处理异步提交问题。

1:分组处理

比如针对一批数据的每一条,都需要调用完创建BAPI之后再调用修改BAPI对其修改,则可以先统一进行创建处理,再进行修改处理,通常当所有单据创建完之后,最先创建的单据应该早已提交更新完毕,示例如下:

改造前:

...
LOOP AT objects.CALL FUNCTION 'BAPI_OBJECT_CREATE'.CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'IMPORTINGWAIT = 'X'.CALL FUNCTION 'BAPI_OBJECT_CHANGE'.CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'IMPORTINGWAIT = ' '.ENDIF.
ENDLOOP.

改造后:

...
LOOP AT objects.CALL FUNCTION 'BAPI_OBJECT_CREATE'.CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'IMPORTINGWAIT = ' '.
ENDLOOP.
LOOP AT objects.IF object not exists.APPEND object TO object_work_listELSE.CALL FUNCTION 'BAPI_OBJECT_CHANGE'.CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'IMPORTINGWAIT = ' '.ENDIF.
ENDLOOP.
Reprocess the objects in object_work_list and wait

2:SET UPDATE LOCAL TASK

SET UPDATE LOCAL TASK会忽略IN UPDATE TASK附加项,使BAPI中数据库更新的过程以本地更新的方式在当前会话内部单独执行,而非注册到VB更新进程中,并且COMMIT WORK会隐式的添加同步提交,但每次COMMIT WORK之后,本地更新会被禁用,所以需要的时候需要在每次调用BAPI之前执行SET UPDATE LOCAL TASK语句来开启本地更新,该方式适用于数据库提交函数中没有触发异步远程RFC的BAPI,例如BAPI_PRODORDCONF_CREATE_TT。


3:使用时间戳+WHILE

通过下面的代码,可以将等待时间减少到尽可能短的等待时间 ,具体取决于使用情况,从而不会浪费额外多余的时间。

DATA: BEGIN OF ls_time,start   TYPE timestampl,now     TYPE timestampl,elapsed TYPE tzntstmpl,         " 目前已运行时间limit   TYPE tzntstmpl VALUE 3, " 最大等待时间END OF ls_time.GET TIME STAMP FIELD ls_time-start.WHILE ls_time-elapsed < ls_time-limit.SELECT SINGLE * INTO @DATA(LS_XXX) FROM XXXX WHERE ...IF LS_XXX IS NOT INITIAL.EXIT.ENDIF.GET TIME STAMP FIELD ls_time-now.ls_time-elapsed = cl_abap_tstmp=>subtract(tstmp1 = ls_time-nowtstmp2 = ls_time-start).ENDWHILE. " elapsed time

 4:使用模式为 U 或 V 的 ENQUEUE_XXXX 功能模块

当您使用适当的功能模块并使用模式 U、V(或 W)时,它将检查锁是否冲突。此处的 SAP 帮助示例:使用锁定模式 U、V 和 W - SAP 锁定概念 - SAP 库中对此进行了详细说明。这里没有提到的是 _WAIT 参数。将此参数设置为 (abap_true 或 'X') 将使函数调用等待预定时间以释放锁。美妙之处在于,这不仅适用于您设置锁定的标准模式,而且还适用于碰撞检查。

CALL FUNCTION 'ENQUEUE_EVVBAKE'EXPORTINGmode_vbak      = 'V'              " Lock mode for table VBAKvbeln          = l_sales_order    " 02th enqueue argument_wait          = abap_trueEXCEPTIONSforeign_lock   = 1system_failure = 2others         = 3.

这种方法的好处是无需手动实现等待逻辑。


5:增强

如果以上方式都不能满足需求,则可以考虑将BAPI复制出来,找到其中控制异步的逻辑,通过增强来添加同步提交控制参数,使得BAPI以同步方式提交,一个案例如下:SAP CO11N BAPI_PRODORDCONF_CREATE_TT连续报工异步更新导致COGI解决方案-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/DeveloperMrMeng/article/details/139811212?spm=1001.2014.3001.5501SAP 报工BAPI中的 UPDATA TASK 和 BACKGROUND TASK_abap in backround task 和in update task的区别-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/DeveloperMrMeng/article/details/140174352?spm=1001.2014.3001.5501


参考链接:

Updates in the SAP System (BC-CST-UP) | SAP Help Portalicon-default.png?t=N7T8https://help.sap.com/docs/SAP_NETWEAVER_701/6d9bbcd26c4b101488b4a6a282b09136/5f6f8337dd34ca76e10000009b38f8cf.html?locale=en-US&q=V2%20Update%28Asynchronous%20Update%29


以上,如有不对,欢迎指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/44473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编译打包自己的云手机(redroid)镜像

前言 香橙派上跑云手机可以看之前的文章&#xff1a; 香橙派5plus上跑云手机方案一 redroid(带硬件加速)香橙派5plus上跑云手机方案二 waydroid 还有一个cuttlefish方案没说&#xff0c;后面再研究&#xff0c;cuttlefish的优势在于可以自定义内核且selinux是开启的&#xf…

Aop切面编程(2)--代理模式

1、代理模式的理解&#xff1a;不修改A对象的代码的基础上&#xff0c;对A代码块进行拓展。通过创建ProxyA代理对象&#xff0c;拓展A对象并调用A对象的核心功能&#xff1b; 即&#xff1a;不修改对象的源码基础上&#xff0c;创建代理对象&#xff0c;进行功能的附加和增强&…

端到端拥塞控制的本质

昨天整理了一篇 bbr 的微分方程组建模(参见 bbr 建模)&#xff0c;算是 bbr 算法终极意义上的一个总结&#xff0c;最后也顺带了对 aimd 的描述&#xff0c;算是我最近比较满意的一篇分享了。那么接下来的问题&#xff0c;脱离出具体算法&#xff0c;上升到宏观层面&#xff0c…

uniapp微信小程序 TypeError: $refs[ref].push is not a function

我的写法 this.$refs.addPopup.open();报错 打印出来是这样的 解决 参考未整理 原因 在当前页面使用的v-for循环 并且循环体内也有组件使用了ref&#xff08;而我没有把每个ref做区别命名&#xff09; 这样就导致了我有很多同名的ref&#xff0c;然后就报错了 解决办法&a…

AI人工智能作词,为音乐注入未来之力

在当今的音乐世界中&#xff0c;创新的力量不断推动着边界的拓展&#xff0c;而人工智能作词正以其独特的魅力&#xff0c;成为引领音乐走向未来的强大动力。 “妙笔生词智能写歌词软件&#xff08;veve522&#xff09;”无疑是这股浪潮中的璀璨明星。它利用先进的人工智能技术…

input上传--upload

1.HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>上传文件</title><link rel"…

数据结构——线性表(C语言实现)

写在前面&#xff1a; 在前面C语言的结构体学习中&#xff0c;我提及了链表的操作&#xff0c; 学习数据结构我认为还是需要对C语言的数组、函数、指针、结构体有一定的了解&#xff0c;不然对于结构体的代码可能很难理解&#xff0c;特别是一些书籍上面用的还是伪代码&#xf…

OpenGL笔记一之基础窗体搭建以及事件响应

OpenGL笔记一之基础窗体搭建以及事件响应 总结自bilibili赵新政老师的教程 code review! 文章目录 OpenGL笔记一之基础窗体搭建以及事件响应1.运行2.目录结构3.main.cpp4.CMakeList.txt 1.运行 2.目录结构 01_GLFW_WINDOW/ ├── CMakeLists.txt ├── glad.c ├── main…

Linux基于centos7指令初学3

date指令 作用&#xff1a; date指令可以查看时间 这个指令可以进行格式化 格式&#xff1a;date %想要的内容 Y&#xff1a;年份 m&#xff1a;月份 d&#xff1a;日 H&#xff1a;时 M&#xff1a;分 S&#xff1a;秒 时间分界线可以由…

LabVIEW比例压力控制阀自动测试系统

开发了一套基于LabVIEW编程和PLC控制的比例控制阀自动测试系统。该系统能够实现共轨管稳定的超高压供给&#xff0c;自动完成比例压力控制阀的耐久测试、流量滞环测试及压力-流量测试。该系统操作简便&#xff0c;具有高精度和高可靠性&#xff0c;完全满足企业对自动化测试的需…

安装jenkins最新版本初始化配置及使用JDK1.8构建项目详细讲解

导读 1.安装1.1.相关网址1.2.准备环境1.3.下载安装 2. 配置jenkins2.1.安装插件2.2.配置全局工具2.3.系统配置 3. 使用3.1.配置job3.2.构建 提示&#xff1a;如果只想看如何使用jdk1.8构建项目&#xff0c;直接看3.1即可。 1.安装 1.1.相关网址 Jenkins官网&#xff1a;https…

Hadoop-25 Sqoop迁移 增量数据导入 CDC 变化数据捕获 差量同步数据 触发器 快照 日志

章节内容 上节我们完成了如下的内容&#xff1a; Sqoop MySQL迁移到HiveSqoop Hive迁移数据到MySQL编写脚本进行数据导入导出测试 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机…

计算机的错误计算(二十九)

摘要 &#xff08;1&#xff09;讨论近似值的错误数字个数。有时&#xff0c;遇到数字9或0, 不太好确认近似值的错误数字个数。&#xff08;2&#xff09;并进一步解释确认计算机的错误计算&#xff08;二十八&#xff09;中一个函数值的错误数字个数。 理论上&#xff0c;我…

百日筑基第十九天-一头扎进消息队列2

百日筑基第十九天-一头扎进消息队列2 消息队列的通讯协议 目前业界的通信协议可以分为公有协议和私有协议两种。公有协议指公开的受到认可的具有规 范的协议&#xff0c;比如 JMS、HTTP、STOMP 等。私有协议是指根据自身的功能和需求设计的协 议&#xff0c;一般不具备通用性&…

数学建模·熵权法

熵权法 一种计算评价指标之间权重的方法。熵权法是一种客观的方法&#xff0c;没有主观性&#xff0c;比较可靠。 具体定义 熵权法的核心在于计算信息熵&#xff0c;信息熵反映了一个信息的紊乱程度&#xff0c;体现了信息的可靠性 具体步骤 Step1正向化处理 将所以评价指标转…

智能家居装修怎么布线?智能家居网络与开关插座布置

打造全屋智能家居。计划的智能家居方案以米家系列为主&#xff0c;智能家居联网方案以无线为主。装修前为了装备智能家居做了很多准备工作&#xff0c;本文深圳侨杰智能分享一个智能家居装修和布线方面的心得与实战知识。希望能对大家的装修有所帮助。 ​1.关于网络 如果房子比…

HTML基本标签(二)

HTML基本标签&#xff08;二&#xff09; 表格标签 table媒体元素audio 音频vido 视频 form 表单元素 表格标签 table <!-- caption 代表表格标题相关属性border 边框cellpadding 设置单元格内填充cellspacing 设置单元格间空隙width 设置表格宽度&#xff0c;默认是内容撑…

结合实体类型信息1——基于本体的知识图谱补全深度学习方法

1 引言 1.1 问题 目前KGC和KGE提案的两个主要缺点是:(1)它们没有利用本体信息;(二)对训练时未见的事实和新鲜事物不能预测的。 1.2 解决方案 一种新的知识图嵌入初始化方法。 1.3 结合的信息 知识库中的实体向量表示&#xff0b;编码后的本体信息——>增强 KGC 2基…

基于AT89C51单片机超声波水位液位控制系统设计(含文档、源码与proteus仿真,以及系统详细介绍)

本篇文章论述的是基于AT89C51单片机的1616点阵LED显示器字符滚动显示设计的详情介绍&#xff0c;如果对您有帮助的话&#xff0c;还请关注一下哦&#xff0c;如果有资源方面的需要可以联系我。 目录 设计任务与要求 原理图 仿真图 代码 系统论文 资源下载 设计任务与要求…

IDEA的JAVA版本没有8怎么办

问题&#xff1a; 很多小伙伴会出现如下的情况&#xff0c;java的版本很高&#xff0c;没有8 解决 更换IDEA内置的Server URL的镜像地址 就是这个 把其中的地址换成 https://start.aliyun.com/ https://start.aliyun.com/ 我们可以看到JAVA 8就出现了