SAP中的 UPDATA TASK 和 BACKGROUND TASK
前言:
记录这篇文章起因是调查生产订单报工问题引申出来的一个问题,后来再次调查后了解了其中缘由,大概记录以下,如有不对,欢迎指正。问题原贴如下:
SAP CO11N BAPI_PRODORDCONF_CREATE_TT连续报工异步更新导致COGI解决方案-CSDN博客https://blog.csdn.net/DeveloperMrMeng/article/details/139811212?spm=1001.2014.3001.5501
当时疑惑的点是为什么更新进程明明是被COMMIT WORK AND WAIT触发的,但为什么仍然会有锁定问题,经过后来再次debug后发现了问题所在,在更新进程中,货物移动的处理是放在一个background task异步tRFC去处理的,是一个立即开始独立运行的进程,主程序中的同步提交只会等更新进程执行完,并不会等这个异步tRFC执行完毕,因为是不同的进程,而这个异步tRFC中在货物移动时会再次对订单上锁,所以当这个异步tRFC没处理完时,立即进行下一次报工就有可能出现锁定问题。
tRFC流程:
问题说明:
针对于报工BAPI,大致的执行流程如上图所示,
- 将所有检查通过的数据库提交任务绑定至同一个LUW;
- 由COMMIT WORK AND WAIT触发同步提交;
- Debug模式可以在SM13中观测到所有注册的更新模块,并且主程序中的锁会被带到更新进程中去,系统将按照注册顺序依次执行,通常这些模块中只包含数据库增删改操作,执行完所有模块后,系统统一提交,并释放所有锁,如果失败,则会统一回滚,并会收到一个dump快件,也会释放所有锁;
- 在标准设计中,货物移动的处理是预先存在AFFW表中,由最后一个更新模块(CO_RU_VB_CONFIRMATION_POST)处理,在这个模块中,将货物移动的处理放在了BACKGROUND TASK中,查看F1说明文档可以看到这是一种已过时的用于绑定事务性RFC的技术,通过该方式注册的函数会立即开始,并且独立异步执行,通过进一步debug,发现货物移动的处理涉及生产订单处理时会再次对订单上锁;
- 程序结束,因为IN BACKGROUND TASK注册的函数是独立的进程,所以如果该进程还没有执行完毕,在下一次针对该订单进行报工的时候就会出现锁定错误;
- 本次执行结束后,第二次针对同一订单处理时,如果异步RFC执行完毕,则第二次将会成功处理(报工成功,货物移动成功);
- 如果报工时异步RFC尚未处理完毕,第二次处理则会因为锁定直接报错(报工失败,货物移动失败);
- 如果第二次报工时上一次的异步RFC尚未开始处理,但处理第二次货物移动时刚好上一次的异步RFC处理已经开始,则可能会出现报工成功,货物移动因为锁定进入COGI(报工成功,货物移动失败);
这也是为什么调用了BAPI之后COMMIT WORK AND WAIT或者调用BAPI前指定了SET UPDATE LOCAL TASK没有生效的原因。
标准BAPI Debug确认过程:
设置好断点,并打开系统调试和更新调试。
同步提交后进入更新进程:
SM13可以看到注册了以下的更新函数模块,其中对自动货物移动的处理在最后一个函数中:
继续调试:
针对最后一个函数重点关照:
标准逻辑就是在此处触发异步的TRFC去处理货物移动的逻辑,此时打开TRFC调试,则该函数模块不会立即执行,会使其注册到SM58,方便进行后续手工处理调试,如果不勾选则会立刻执行,不会等待手工处理。
F8执行之后,可以看到此时已返回主程序,针对订单的锁也已经释放,但处理货物移动的函数被我们注册到了SM58,等待处理,所以SM58进行下一步调试,看看里面做了些什么。
SM58:
在下面这段处理中将会对订单再次上锁:
只有等该函数执行结束后才会释放锁,所以如果此时再次对该订单发起报工时就会出现锁定问题。
以上差不就是整个关键的debug过程,为了再次验证这个猜想,我重新写了一份测试代码进行验证,以下代码可以复现还原这个问题。
测试代码:
*&---------------------------------------------------------------------*
*& Report ZUPDATE_TEST
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zupdate_test.DATA:lt_test TYPE STANDARD TABLE OF ztest_trfc,ls_test TYPE ztest_trfc.DO 1 TIMES.TRY .ls_test-uuid = cl_uuid_factory=>create_system_uuid( )->create_uuid_x16( ).CATCH cx_uuid_error.ENDTRY.ls_test-uname = sy-uname.CALL FUNCTION 'ZNOMAL_TEST'EXPORTINGi_test = ls_test.COMMIT WORK AND WAIT.IF sy-subrc = 0.WRITE:'Update success:',ls_test-uuid.ELSE.WRITE:'Update failed:',ls_test-uuid.ENDIF.
ENDDO.
FUNCTION znomal_test.
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" VALUE(I_TEST) TYPE ZTEST_TRFC
*"----------------------------------------------------------------------CALL FUNCTION 'ENQUEUE_E_TABLE'EXPORTING
* MODE_RSTABLE = 'E'tabname = 'ZTEST_TRFC'
* VARKEY =
* X_TABNAME = ' '
* X_VARKEY = ' '
* _SCOPE = '2'
* _WAIT = ' '
* _COLLECT = ' 'EXCEPTIONSforeign_lock = 1system_failure = 2OTHERS = 3.IF sy-subrc <> 0.MESSAGE 'Lock Failed!' TYPE 'E'.ENDIF.CALL FUNCTION 'ZCALL_UPDATE_TASK' IN UPDATE TASKEXPORTINGi_test = i_test.ENDFUNCTION.
FUNCTION zcall_update_task.
*"----------------------------------------------------------------------
*"*"更新函数模块:
*"
*"*"本地接口:
*" IMPORTING
*" VALUE(I_TEST) TYPE ZTEST_TRFC
*"----------------------------------------------------------------------CALL FUNCTION 'ZBACKGROUND_TASK_TEST' IN BACKGROUND TASKEXPORTINGi_test = i_test.ENDFUNCTION.
FUNCTION zbackground_task_test.
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" VALUE(I_TEST) TYPE ZTEST_TRFC
*"----------------------------------------------------------------------SET UPDATE TASK LOCAL.DO.SELECT SINGLE * INTO @DATA(ls_lock1) FROM z13065_lock WHERE upd_id = '13065'.IF ls_lock1-zlock = '1'.EXIT.ENDIF.ENDDO.CALL FUNCTION 'ENQUEUE_E_TABLE'EXPORTING
* MODE_RSTABLE = 'E'tabname = 'ZTEST_TRFC'
* VARKEY =
* X_TABNAME = ' '
* X_VARKEY = ' '
* _SCOPE = '2'
* _WAIT = ' '
* _COLLECT = ' 'EXCEPTIONSforeign_lock = 1system_failure = 2OTHERS = 3.IF sy-subrc <> 0.MESSAGE 'Lock Failed!' TYPE 'E'.ENDIF.DO.SELECT SINGLE * INTO @DATA(ls_lock2) FROM z13065_lock WHERE upd_id = '13065'.IF ls_lock2-zlock = '2'.EXIT.ENDIF.ENDDO.* CALL FUNCTION 'ZUPDATE_TASK_TEST' IN UPDATE TASK
* EXPORTING
* is_test = i_test.MODIFY ztest_trfc FROM i_test.COMMIT WORK.ENDFUNCTION.
通过LOCK表中的标识字段可以控制进程执行位置,测试过程就不贴图了,感兴趣的可以自己debug看看,根据观察SM12,SM50,SM13,SM58等标准事务代码中的信息就可以理解整个执行过程。
总结:
大多数标准BAPI的更新都是放在更新进程(CALL FUNCTION XXX IN UPDATE TASK)中去统一提交数据库更新的,可以根据COMMIT WORK是否添加AND WAIT附加项来决定是否同步更新,而CALL FUNCTION XXX IN BACKGROUND TASK则以已单独进程进行异步更新的,独立于对话框程序,属于两种互相独立的更新进程。
参考资料:
在后台任务中调试 FM - SAP Community
什么是LUW?LUW如何运作?不同类型的 LUW ... - SAP 社区
SAP LUW - ABAP 关键字文档
Transactional RFC (tRFC) | SAP Help Portal
相关文章:

SAP中的 UPDATA TASK 和 BACKGROUND TASK
前言: 记录这篇文章起因是调查生产订单报工问题引申出来的一个问题,后来再次调查后了解了其中缘由,大概记录以下,如有不对,欢迎指正。问题原贴如下: SAP CO11N BAPI_PRODORDCONF_CREATE_TT连续报工异步更…...

UDP协议:独特之处及其在网络通信中的应用
在网络通信领域,UDP(用户数据报协议,User Datagram Protocol)是一种广泛使用的传输层协议。与TCP(传输控制协议,Transmission Control Protocol)相比,UDP具有其独特的特点和适用场景…...
支持向量机(Support Vector Machine,SVM)及Python和MATLAB实现
支持向量机(Support Vector Machine,SVM)是一种经典的机器学习算法,广泛应用于模式识别、数据分类和回归分析等领域。SVM的背景可以追溯到1990s年代,由Vladimir Vapnik等人提出,并在之后不断发展和完善。 …...

【RT-thread studio 下使用STM32F103-学习sem-信号量-初步使用-线程之间控制-基础样例】
【RT-thread studio 下使用STM32F103-学习sem-信号量-初步使用-线程之间控制-基础样例】 1、前言2、环境3、事项了解(1)了解sem概念-了解官网消息(2)根据自己理解,设计几个使用方式(3)不建议运行…...
使用nodejs输出著作权申请所需的word版源码
使用nodejs输出著作权申请所需的word版源码 背景 软件著作权申请需要提供一份80页的word版源代码,如果手工复制源码到word文档中,工作量将无聊到让任何一个DAO人员血压爆表,因此我们不得不编写一个简单的文本处理代码,通过自动方…...
[Vite]vite-plugin-react和vite-plugin-react-swc插件原理了解
[Vite]vite-plugin-react和vite-plugin-react-swc插件原理了解 共同的作用 JSX 支持:插件为 React 应用程序中的 JSX 语法提供支持,确保它可以被正确地转换为 JavaScript。Fast Refresh:提供热更新功能,当应用程序在开发服务器上…...
记一次使用“try-with-resources“的语法导致的BUG
背景描述 最近使用try-catch的时候遇到了一个问题,背景是这样的:当第一次与数据库建立连接以后执行查询完毕并没有手动关闭连接,但是当我第二次获取连接的时候报错了,显示数据库连接失败,连接已经关闭。 org.postgres…...

用Excel处理数据图像,出现交叉怎么办?
一、问题描述 用excel制作X-Y散点图,意外的出现了4个交叉点,而实际上的图表数据是没有交叉的。 二、模拟图表 模拟部分数据,并创建X-Y散点图,数据区域,X轴数据是依次增加的,因此散点图应该是没有交叉的。…...

SpringBoot | 大新闻项目后端(redis优化登录)
该项目的前篇内容的使用jwt令牌实现登录认证,使用Md5加密实现注册,在上一篇:http://t.csdnimg.cn/vn3rB 该篇主要内容:redis优化登录和ThreadLocal提供线程局部变量,以及该大新闻项目的主要代码。 redis优化登录 其实…...

ESP32——物联网小项目汇总
商品级ESP32智能手表 [文章链接] 用ESP32,做了个siri?!开源了! [文章链接]...

flutter:监听路由的变化
问题 当从路由B页面返回路由A页面后,A页面需要进行数据刷新。因此需要监听路由变化 解决 使用RouteObserver进行录音监听 创建全局变量,不在任何类中 final RouteObserver<PageRoute> routeObserver RouteObserver<PageRoute>();在mai…...

Linux多进程和多线程(六)进程间通信-共享内存
多进程(六) 共享内存共享内存的创建 示例: 共享内存删除 共享内存映射 共享内存映射的创建解除共享内存映射示例:写入和读取共享内存中的数据 写入: ### 读取: 大致操作流程: 多进程(六) 共享内存 共享内存是将分配的物理空间直接映射到进程的⽤户虚拟地址空间中, 减少数据在…...
ruoyi后台修改
一、日志文件过大分包 \ruoyi-admin\src\main\resources\logback.xml <!-- 系统日志输出 --> <appender name"file_info" class"ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/sys-info.log</file><!…...

macOS查看系统日志的方法
1、command空格键打开搜索框,输入‘控制台’并打开 2、选择日志报告,根据日期打开自己需要的文件就可以...

数字信号处理及MATLAB仿真(3)——采样与量化
今天写主要来编的程序就是咱们AD变换的两个步骤。一个是采样,还有一个是量化。大家可以先看看,这一过程当中的信号是如何变化的。信号的变换图如下。 先说说采样,采样是将连续时间信号转换为离散时间信号的过程。在采样过程中,连续…...

云端AI大模型群体智慧后台架构思考
1 大模型的调研 1.1 主流的大模型 openai-chatgpt 阿里巴巴-通义千问 一个专门响应人类指令的大模型。我是效率助手,也是点子生成机,我服务于人类,致力于让生活更美好。 百度-文心一言(千帆大模型) 文心一言"…...

算法系列--分治排序|再谈快速排序|快速排序的优化|快速选择算法
前言:本文就前期学习快速排序算法的一些疑惑点进行详细解答,并且给出基础快速排序算法的优化版本 一.再谈快速排序 快速排序算法的核心是分治思想,分治策略分为以下三步: 分解:将原问题分解为若干相似,规模较小的子问题解决:如果子问题规模较小,直接解决;否则递归解决子问题合…...

强化学习编程实战-1-一个及其简单的强化学习实例(多臂赌博机)
1.1 多臂赌博机 一台拥有K个臂的机器,玩家每次可以摇动K个臂中的一个,摇动后,会吐出数量不等的金币,吐出金币的数量服从一定的概率分布,而且不同臂的概率分布不同。 多臂赌博机的问题是:假设玩家共有N次摇地…...

Golang语法规范和风格指南(一)——简单指南
1. 前引 一个语言的规范的学习是重要的,直接关系到你的代码是否易于维护和理解,同时学习好对应的语言规范可以在前期学习阶段有效规避该语言语法和未知编程风格的冲突。 这里是 Google 提供的规范,有助于大家在开始学习阶段对 Golang 进行一…...
数据机构记录顺序表-笔记1
一、线性表的基本概念 数据元素:线性表中的基本单位,每个元素都是线性表的一部分。 数据项:数据元素的具体值。 存储位置:线性表中的元素在内存中的具体存储位置。 线性表按存储结构可以分为顺序表和链表两大类: 1.1…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...