Update function的问题和解决方案

2023-11-01

DN的过账一般使用的是都是 Function: WS_DELIVERY_UPDATE ,其实这是一个经常使用到的函数,注意,这不是一个BAPI,只是一个函数,但是这个函数里面有一个update funtion ,所以这个函数并没有返回参数 return ( update 和异步的funtion都没有返回参数 )。

DN的创建/修改 / 以及过账中BAPI,创建利润中心,成本中心: 

BAPI_OUTB_DELIVERY_CREATE_SLS 

BAPI_OUTB_DELIVERY_CREATE_STO

BAPI_OUTB_DELIVERY_CHANGE

BAPI_PROFITCENTER_CREATE

BAPI_COSTCENTER_CREATEMULTIPLE

都使用的这个函数,但是这个函数里面会调用一个 update funtion,

路径如下:

WS_DELIVERY_UPDATE_2

delivery_save

beleg_sichern_01

beleg_sichern_post

lieferungen_verbuchen_db

 这就导致即使我们在外部使用 commit work and wait. 

这样此时我们 去读取数据库LIKP获取字段状态的时候,偶尔会获取不到最新值。

此时场景一:交货单过账的时候,由于该函数没有返回参数,所以没有如果直接使用下面的SQL判断,是无法得到最新的结果。

SELECT SINGLE * FROM likp INTO @DATA(ls_likp) WHERE vbeln = @lf_vbeln AND wbstk = 'C'.
        IF sy-subrc = 0. " 过账成功
          ev_message = ev_message && '过账成功'.
        ELSE.
          ev_message = ev_message && '过账失败'.
        ENDIF.

此时一般方法是:

DO循环中,间隔一秒去读取记录,读到就退出,一般会尝试读个3-5次。

这种方法基本上不会出错,但是太慢了,慢到经常大批量做的时候受不了。

第二种:

本地调用 SET UPDATE TASK LOCAL 

当使用 SET UPDATE TASK LOCAL  的时候,会将所有的更新函数( IN UPDATE TASK 函数, IN COMMIM的例程  )的数据注册到SAP MEMORY,当使用 COMMIT WORK 的时候,系统会在当前进程执行更新语句。这样只有在UPDATE 函数的逻辑更新结束才会执行后面的自定义的逻辑。

但是这样会有一个问题,当标准函数发生Dump的时候,后面的自定义程序也会中断,不使用本地调用的话不会这样,而是在SM13中看到错误的日志,自定义部分会正常执行。

      la_vbkok-vbeln_vl           = lf_vbeln.
      la_vbkok-wabuc              = 'X'.
      la_vbkok-wadat_ist          = sy-datum.
      LOOP AT lt_item INTO ls_item.
        ls_vbpok-vbeln_vl = ls_item-deliv_numb. "delivery
        ls_vbpok-posnr_vl = ls_item-deliv_item.
        ls_vbpok-vbeln = ls_item-deliv_numb.  "delivery
        ls_vbpok-posnn = ls_item-deliv_item.
        ls_vbpok-matnr = ls_item-material.  "delivery
        ls_vbpok-pikmg = ls_item-dlv_qty.
        ls_vbpok-lgort = 'L001'.
        ls_vbpok-kzlgo = 'X'.
        ls_vbpok-xwmpp = 'X'.
        APPEND ls_vbpok TO lt_vbpok.
      ENDLOOP.
      SET UPDATE TASK LOCAL.
      CALL FUNCTION 'WS_DELIVERY_UPDATE'
        EXPORTING
          vbkok_wa  = la_vbkok
          commit    = 'X'
          delivery  = lf_vbeln
        TABLES
          vbpok_tab = lt_vbpok
          prot      = lt_prot.

      LOOP AT lt_prot INTO ls_prot WHERE msgty CA 'AEX'.
        CALL FUNCTION 'MESSAGE_TEXT_BUILD'
          EXPORTING
            msgid               = ls_prot-msgid
            msgnr               = ls_prot-msgno
            msgv1               = ls_prot-msgv1
            msgv2               = ls_prot-msgv2
            msgv3               = ls_prot-msgv3
            msgv4               = ls_prot-msgv4
          IMPORTING
            message_text_output = lv_message.
        ev_msgty = cs_status_e.
        CONCATENATE ev_message lv_message ';' INTO ev_message.
      ENDLOOP.

      IF sy-subrc = 0.
      ELSE.

        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = space.

        SELECT SINGLE * FROM likp INTO @DATA(ls_likp) WHERE vbeln = @lf_vbeln AND wbstk = 'C'.
        IF sy-subrc = 0. " 过账成功
          wa_input-dn_post = 'X'.
          ev_message = ev_message && '过账成功'.
        ELSE.
          ev_msgty = cs_status_e.
          ev_message = ev_message && '过账失败'.
        ENDIF.
      ENDIF.

方法二:在funtion 外面再使用一个update function ,

 交货单自动过账程序原来的逻辑期望通过这种方式确保交货单过账的更新和自定义表的更新都在更新进程中执行, 如果交货单更新报错,会中断更新过程, 自定义表也就不会更新了.

特殊BAPI函数的问题

但是交货单的过账BAPI使用这种方式时. 系统没有确保二者的更新写入同一个更新进程.而是写到了不同的更新进程中. 如图二(两个更新在不同的更新进程中).

交货单中的底层逻辑有时候会启动另外一个进程执行函数.新启动的进程中的更新就无法和当前进程的更新注册到同一个更新进程中了. 可以通过在标准更新过程中及自定义更新函数中强制报错模拟出这个场景.

问题的发现

最近发现自动过账程序表中记录的单据过账状态与单据的实际过账状态不一致.

自动过账程序根据写入ZTA_DN_POST表的交货单, 调用BAPI 执行交货单过账, 成功后,更新表中的处理标记 ( ZTA_DN_POST-VPROC='S' ).

详见链接

无峰,公众号:ABAP 技巧与实战SAP开发框架系列之 自动单据

更新不一致一般都能在SM13中找到响应的报错信息.大部分报错是在程序或表结构修改上传生产系统时产生的.

所以从传输或作业机制中需要为后台作业保留一个空窗期, 程序传输在这个空窗期中执行. 以便减少因为传输导致的后台执行报错. 

快速方便的的后台作业调度

无峰,公众号:ABAP 技巧与实战SAP批量后台作业定义和管控

自动过账更新逻辑

调用BAPI执行交货单过账. 判断BAPI调用成功,然后更新ZTA_DN_POST. 更新语句放入更新函数,使用IN UPDATE TASK 调用. 最后执行COMMIT WORK. 提交更新.

 

 三

IN UPDATE TASK语句功能

查看IN UPDATE TASK 语句的帮助可以了解到 IN UPDATE TASK 中的代码会注册要更新的数据到更新进程中. COMMIT WORK 语句时才会触发所有更新语句的执行. 

如果业务单据执行过程报错, 在事务代码SM13中可以看到更新条目,更新条目中能看到标准更新和自定义表更新在同一个更新进程中. 如图一

交货单自动过账程序原来的逻辑期望通过这种方式确保交货单过账的更新和自定义表的更新都在更新进程中执行, 如果交货单更新报错,会中断更新过程, 自定义表也就不会更新了.

 图一

特殊BAPI函数的问题

但是交货单的过账BAPI使用这种方式时. 系统没有确保二者的更新写入同一个更新进程.而是写到了不同的更新进程中. 如图二(两个更新在不同的更新进程中).

 

具体原因的猜想

SPRING

交货单中的底层逻辑有时候会启动另外一个进程执行函数.新启动的进程中的更新就无法和当前进程的更新注册到同一个更新进程中了. 可以通过在标准更新过程中及自定义更新函数中强制报错模拟出这个场景.

图二

问题解决的方式

在调用交货单过账BAPI函数之前

 

执行SET LOCAL UPDATE 语句. 该语句会让所有的更新函数(IN UPDATE TASK 调用)的数据注册到SAP MEMORY 中. 执行COMMIT WORK语句时, 系统在当前进程中执行数据更新的语句. 这样可以确保标准更新和自定义的更新都在当前进程中执行. 如果标准更新报错,进程会中止,自定义表的更新也就会失败. 

但是这样设置有一个弊端: 如果更新报错,程序的后续处理会中止. 如果因为某个单据数据的异常导致该单据一直更新异常. 设置本地更新就会导致后续单据都无法处理. 

 六

总结

尽量使用 IN UPATE TASK 提交自定义表的更新, 应用系统的更新进程机制, 如果存在更新错误,可以通过SM13查看报错的信息.

尽量不使用SET UPDATE TASK LOCAL ?(这个结论可能会有不同的看法)

因为这个语句会让当前进程执行更新过程,更新报错会导致程序中止. 影响其它正确单据的执行.同时无法使用SM13查看报错.

但是对交货单过账等比较变态的BAPI函数(函数中又启动了新的进程执行逻辑). 在发现程序更新不一致时, 建议启用 SET UPDATE TASK LOCAL 以确保更新一致
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Update function的问题和解决方案 的相关文章

  • SAP ABAP ME23N 采购订单打印输出

    本人诚心接ABAP远程开发任务 价格公道 有需要的联系我 欢迎个人 甲方爸爸 乙方私信联系 完成的功能是ME23N 点击打印预览 客制化用户自己的打印模板 首先需要先配置打印输出 路径 spro gt 物料管理 gt 采购 gt 消息 gt
  • sap doi技术操作excel的方法

    OLE是和微软OFFICE做接口 比较老的技术 DOI是SAP自己搞的 相对是后出来的技术 同样可以操作EXCEL 有一些方法 get sheets select range cell format set ranges format 等等
  • SAP ABAP 中的异步调用

    举例场景 创建采购申请的接口中 在执行完BAPI之后返回了一个PR 接着就会执行到commit提交的接口 然如果还需要在创建的时候直接审批 那么就需要再调用PR审批的BAPI 但是你会发现有的PR 在ME23N查看的时候是审批状态 而有的并
  • 记录一下QM检验批接口,回头补细节

    method ZQM II SI SPCD REC SI SPCD PROCSS INSERT IMPLEMENTATION HERE gt 数据定义部分 TYPES BEGIN OF ty qamv prueflos TYPE qamv
  • FICO F.27 Customer statement 打印

    需求 定制化打印 替换标准的F 27打印 类似于采购订单的打印 但是略有不同 查阅资料之后步骤如下 T code F 27 is SAP standard program to produce customer vendor corresp
  • SAP 在制品明细

    Report ZCO019 REPORT zco019 TABLES matdoc SELECT OPTIONS s bukrs FOR matdoc bukrs OBLIGATORY s bu
  • SAP PO上传异步接口(PO发布Webservice)

    导语 接口是SAP与其他系统进行数据交互的一种方式 在这篇文章中主要讲述通过PO实现的上传接口 即SAP被动接收其他系统发送的数据 注意 对于配置中涉及的基本组件的介绍和创建在前面的博客有说明和介绍 再次不做过多赘述了 一 ESB Ente
  • ALV 中颜色、强调、下划线的样式

    我们正在尝试操作 alv 网格类来获得像 Sap Agenda SSC1 tcode 中那样的结果 即合并列和行 我们发现该类cl calendar control schedule用方法display处理这个问题 我们正在努力理解这个方法
  • 如何让程序在单击按钮时返回表中的多个表字段?

    我正在尝试创建一个程序 允许用户输入foodCode为了收到Item and Description按下按钮后 有没有办法可以将结果放在同一屏幕上的表格中 如何 report demo tables food SELECTION SCREE
  • 如何添加整个包来通过代码传输请求?

    我的任务是以编程方式完成所有这些步骤 创建一个新的传输请求 我设法做到了TR INSERT REQUEST WITH TASKS 将包内容添加到新创建的传输中 这是我陷入困境的部分 释放传输 我设法做到了这一点TR RELEASE REQU
  • 配置SAP用户密码策略(不用重启服务器的方法)

    最近公司审计 给我们提出了要优化密码策略的建议 原因是我们的密码策略太简单了 我稍稍研究了一下 之前是通过RZ10来配置 但是这种方法需要重启服务器 这就比较麻烦 其实有一种方法是通过配置密码策略 不要要重启的方法 事务代码 SECPOL
  • 将 ALV 输出网格中的复选框标记为选中

    我正在使用类创建 ALV 输出网格cl gui alv grid 使用 fieldcatalog 的相应记录将输出表的其中一列定义为复选框 ls fcat checkbox X ls fcat edit X 对于包含复选框的列的所有记录 它
  • CNS0创建交货单没有WBS元素

    1 问题 CNS0创建交货单带不出WBS 但是交货单过账之后 又可以读取到WBS 2 原因 2 1 项目挂料 创建项目挂料时 当物料为通用料 则在网络中挂料时 采购类型为网络预留 当物料为专用料 则在网络中挂料时 采购类型为WBS要素预留
  • SAP搜索帮助的限制值范围样式

    样式一 点击下拉框 输入筛选数据 筛选搜索帮助列表 样式二 点击漏斗 输入筛选数据 筛选搜索帮助列表 参数设置 不同的样式 通过账号的参数设置决定 第一种样式 没有配置F4METHOD 或者配置了参数值为ActiveX 第二种样式 配置了F
  • 除了使用 CONCATENATE 关键字之外,还有其他连接方法吗?

    有没有另一种方法可以在ABAP中连接而不是使用CONCATENATE keyword http help sap com abapdocu 731 en abapconcatenate shortref htm 一个使用的例子CONCATE
  • ALV 列表中的两级列标题

    我想添加一个标题行来对列标题进行分组 Departure Arrival lt This row is what I want to add Airport Gate Date Airport Gate Date O Hare A10 10
  • 隐藏警告的杂注:where 条件中使用的字段可能包含空值

    我正在寻找一个编译指示 可以用来隐藏当选择的 WHERE 条件中使用的字段可能包含数据库中的 NULL 值时生成的编译器警告 阅读 SAP note 1088403 后 我知道这里可能存在问题 但我无法应用那里建议的解决方案 因为我在 WH
  • SELECT 语句中有多个条件?

    首先 我没有 ABAP 经验 我在这里只是猜测 我想向现有报表中的 SELECT 添加条件 现有代码如下所示 SELECT SINGLE FROM EKPO WHERE EBELN GT MSEG EBELN AND EBELP GT MS
  • ABAP中的求值顺序

    ABAP 是否有明确的评估顺序 例如 在表达式中foo bar 是否可以保证哪种方法foo and bar 首先评估 执行 在 ABAP 关键字文档中找不到此类信息 ABAP 文档 arith exp 算术运算符 https help sa
  • 对分组表进行数学运算

    我的问题不在于真正的编程语言 我有一个 ABAP 语言练习 但该语言不是很重要 无论如何 我有一张桌子 我需要计算该职位的总成本 显然是在选择之后 然后 该表将按两个字段 MATNR 和 BUKRS 进行分组 因此我需要知道每个组的头寸总成

随机推荐

  • 下载安装Android Studio教程

    步骤1 下载Android Studio 访问Android Studio官方网站 https developer android com studio 点击 下载Android Studio 按钮 选择适用于您操作系统的版本 然后下载安装
  • Unix Shell 范例精解——awk课后题

    题目数据如下 Mike Harrington 510 548 1278 250 100 175 Christian Dobbins 408 538 2358 155 90 201 Susan Dalsass 206 654 6279 250
  • Three.js 基础- 第 2 章 - 几何体BufferGeometry

    Three js 基础 第 2 章 几何体BufferGeometry Three js教程 几何体BufferGeometry 在Three js中 几何体是3D对象的基本形状 本教程将介绍如何使用缓冲类型几何体BufferGeometr
  • 【独家源码】ssm高校试卷管理系统i0lzr应对计算机毕业设计困难的解决方案

    本项目包含程序 源码 数据库 LW 调试部署环境 文末可获取一份本项目的java源码和数据库参考 系统的选题背景和意义 选题背景 高校试卷管理是教学工作中的重要环节 涉及到试卷的编写 存储 分发和评阅等多个方面 然而 传统的试卷管理方式存在
  • [转]Java 线程池的原理与实现

    最近在学习线程池 内存控制等关于提高程序运行性能方面的编程技术 在网上看到有一哥们写得不错 故和大家一起分享 分享 Java 线程池的原理与实现这几天主要是狂看源程序 在弥补了一些以前知识空白的同时 也学会了不少新的知识 比如 NIO 或者
  • SoftwareSerial库的使用——Arduino软件模拟串口通信

    除HardwareSerial外 Arduino还提供了SoftwareSerial类库 它可以将你的其他数字引脚通过程序模拟成串口通信引脚 通常我们将Arduino UNO上自带的串口称为硬件串口 而使用SoftwareSerial类库模
  • 如何开启计算机cpu虚拟化,电脑开启虚拟化设置的方法 如何开启虚拟化设置

    虚拟化设置的开启其实很简单 因为大家没有接触和操作过 所以一开始会不知所措 虚拟化设置的开启其实很简单 因为大家没有接触和操作过 所以一开始会不知所措 小编在这里为广大玩家深度总计虚拟化开启方法 方便大家在电脑端更流畅的体验手机游戏 虚拟化
  • maven工程依赖的jar包,在本地仓库有,但是pom.xml文件却报错找不到jar包

    例如 Missing artifact com ibm db2 db2jcc license cisuz jar 10 1 但在我本地的仓库中却存在这个jar包 查找了很多的资料发现了两种解决方法 第一种 在eclipse中的window
  • 透彻了解inlining的里里外外——条款30

    Inline函数 多棒的点子 它们看起来像函数 动作像函数 比宏好得多 见条款2 可以调用它们又不需要蒙受函数调用所招致的额外开销 你还能要求更多吗 你实际获得的比想到的还多 因为 免除函数调用成本 只是故事的一部分而已 编译器最优化机制通
  • 2021美赛F题

    2021年 问题E 重新优化食物系统 最近的事件向我们表明 我们的全球粮食系统即使在世界的某些地区也是不稳定的 它通常服务于全世界 这些不稳定的部分原因是我们目前的全球气候变化 庞大的国内和国际食品生产商和经销商体系 这个食物系统 使食物的
  • CUDA矩阵乘法优化

    前言 纸上的来终觉浅 绝知此事要躬行 naive写法 一个矩阵的乘法简单如下 C A B 一般用gemm A B C M N K 来表示 其中的m n k代表的位置如下 默认是k表示消失的纬度 上图的红色虚线围起来的是一个block要负责的
  • MySQL存储引擎InnoDB与Myisam的六大区别

    MySQL有多种存储引擎 每种存储引擎有各自的优缺点 可以择优选择使用 MyISAM InnoDB MERGE MEMORY HEAP BDB BerkeleyDB EXAMPLE FEDERATED ARCHIVE CSV BLACKHO
  • MySQL注入绕安全狗脚本 -- MySQLByPassForSafeDog,以及端口爆破工具 -- PortBrute配置使用

    工具介绍 此Tamper仅仅适用于MySQL数据库 在SQLMap使用过程中添加参数 tamper MySQLByPassForSafeDog 安装与使用 1 安装网站安全狗Apache最新版 2 启用安全狗 不加MySQLByPassFo
  • vue.js组件详解

    一 组件的概念及复用 1 1 为什么要使用组件 组件 component 是vue js最核心的功能 用来实现局部 特定 功能效果的代码集合 html css js image 组件是可复用的 Vue 实例 把一些公共的模块抽取出来 然后写
  • anaconda创建和删除环境

    一 创建环境 在菜单栏中打开Anaconda Prompt 它是一个命令行界面 我们输入下面命令创建环境 这里的py37是我随意起的环境名 大家任意取好记为主 后面的python版本也是自由指定 中间只有一个等号 例如我这里是想创建pyth
  • unicode编码表

    unicode编码表 转载于 近來情轉深的博客 http jlqzs blog 163 com blog static 2125298320070101826277 另附一个汉字转化unicode编码的网页工具 http www bangn
  • 使用别人编译的动态库gdb,路径不匹配

    如果你在调试时需要在动态库中打断点 但动态库的路径是别人的路径 可以使用 GDB 的 set substitute path 命令将动态库路径替换为你本地的路径 具体来说 执行以下步骤 启动 GDB 并加载调试目标 使用 info shar
  • WebFlux ServerHttpRequest RequestBody 读取

    MockServerHttpRequest request MockServerHttpRequest post test body test DecoderHttpMessageReader
  • 安卓开发--不走弯路,5步教你快速实现拍照功能(基于安卓13)

    先展示效果 实现基本逻辑很简单 大致5步为 点击按钮 启动相机 拍照 保存相片 展示相片 但是这里面有一些细节对于初次接触安卓的用户并不友好 比如笔者我 折腾了一阵子才梳理出基本流程 下面我将分步骤说明 按着我的步骤即可快速实现拍照功能 目
  • Update function的问题和解决方案

    DN的过账一般使用的是都是 Function WS DELIVERY UPDATE 其实这是一个经常使用到的函数 注意 这不是一个BAPI 只是一个函数 但是这个函数里面有一个update funtion 所以这个函数并没有返回参数 ret