当前位置: 首页 > news >正文

【案例总结】幽灵单据——消失的交货单号

这篇文章应该叫做,《ABAPer在SE37测试BAPI时不COMMIT WORK的后果》 

注意:本篇文章的解答是AI deepseek回答的,如有侵权,立即私聊我,卑微Sesy在线求饶!

目录

背景

解答

一、根本原因分析

二、关键点解读

三、80000001 和 80000002 的命运

结论

80000001 和 80000002 在哪里?

如何避免这种情况?

总结

延申

一、创建测试序列的方法

二、理解 BAPI 的行为


背景

我在SAP系统SE37中测试BAPI:BAPI_OUTB_DELIVERY_CREATE_SLS创建交货单,创建成功,也返回了交货单80000001,但是我在后台表SE16N :LIKP和LIPS表中都没有查询到。然后我继续使用BAPI创建了交货单号80000002,也是相同结果。后面我使用测试序列,在SE37调用bapi后,继续调用bapi:bapi_TRANSACTION_COMMIT,创建了交货单号80000003,然后commit后,就能够在LIKP和LIPS表中找到80000003这个交货单号了。但是!80000001和80000002这两个交货单号消失了,在任何一个后台表都找不到,所以该如何找到80000001和80000002这两个单据呢?

解答

这个问题非常典型,涉及到 SAP BAPI 执行的核心机制:数据库提交(COMMIT)。

一、根本原因分析

BAPI_OUTB_DELIVERY_CREATE_SLS 的机制:这个 BAPI 的主要功能是在内存(应用服务器缓冲区) 中构建交货单所需的所有数据(抬头 LIKP、行项目 LIPS、相关表数据等)。

当它执行成功时,它会:在内存中生成完整的交货单结构。分配一个交货单号(如 80000001, 80000002)。将这个号码通过 RETURN 参数或 DELIVERY 参数(取决于 BAPI 具体版本和参数设置)返回给调用者。

二、关键点解读

它本身并不执行数据库的写入(INSERT/UPDATE)操作! 它只是准备好数据。

数据库持久化(写入硬盘)需要显式提交:要使 BAPI 在内存中准备的数据真正保存到数据库表(LIKP, LIPS, VBTK 等)中,必须显式地提交数据库事务。

在第三次测试中,我调用了 BAPI_TRANSACTION_COMMIT。这个 BAPI 的作用就是:将当前 SAP LUW (Logical Unit of Work) 中所有未提交的数据库更改(包括BAPI_OUTB_DELIVERY_CREATE_SLS 创建的交货单数据)真正写入数据库。执行一个数据库 COMMIT WORK 操作。

这就是为什么只能在数据库表中看到 80000003。

三、80000001 和 80000002 的命运

当只调用 BAPI_OUTB_DELIVERY_CREATE_SLS 而没有调用 BAPI_TRANSACTION_COMMIT 时:交货单数据(80000001, 80000002)只存在于应用服务器的内存缓冲区中。它们尚未被写入数据库表(LIKP, LIPS)。当会话(Session)结束、退出事务码(如 SE37)、或者系统执行隐式回滚时(例如超时、程序异常终止),SAP 会自动执行一个 ROLLBACK WORK。ROLLBACK WORK 的作用就是撤销当前 SAP LUW 中所有未提交的数据库更改。

因此,80000001 和 80000002 的数据被丢弃了,它们从未真正写入数据库。

结论

80000001 和 80000002 在哪里?

它们不存在于数据库(LIKP, LIPS 或任何相关表)中。 因为没有提交,数据从未写入硬盘。它们也不存在于任何临时表或缓冲区中(在会话结束后)。 回滚操作清除了所有痕迹。简单地说:80000001 和 80000002 被系统“丢弃”了。它们只是短暂存在于内存中但未被持久化的编号。 它们不是有效的、可用的交货单。

如何避免这种情况?

始终在成功调用创建/更改数据的 BAPI 后提交事务:

在 SE37 测试时,使用BAPI_TRANSACTION_COMMIT。

在 ABAP 程序中调用 BAPI 时,在检查 RETURN 参数没有错误消息 (TYPE 不是 'E' 或 'A') 后,调用 COMMIT WORK 语句。

abap代码示例:CALL FUNCTION 'BAPI_OUTB_DELIVERY_CREATE_SLS'EXPORTING...IMPORTING...TABLES...return = lt_return." 检查是否有错误LOOP AT lt_return INTO ls_return WHERE type CA 'EA'.EXIT.ENDLOOP.IF sy-subrc <> 0. " 没有严重错误CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'EXPORTINGwait = 'X'. " 等待提交完成ELSE." 处理错误,通常需要调用 BAPI_TRANSACTION_ROLLBACKCALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.ENDIF.

使用测试序列(Test Sequence)功能: 就像第三次测试那样,在 SE37 的测试环境中,可以在调用创建 BAPI 后,紧接着调用 BAPI_TRANSACTION_COMMIT。这是测试这类 BAPI 的标准做法。

总结

80000001 和 80000002 无法找回,因为它们从未被保存到数据库。它们是前两次未提交事务的“幽灵”单据。在 SAP 中,对于创建或修改重要业务数据(如交货单、销售订单、采购订单等)的 BAPI,成功调用 BAPI 并返回成功信息(如单号)只表示数据在内存中准备好了,必须再执行显式的 COMMIT 操作(通过 BAPI_TRANSACTION_COMMIT 或 COMMIT WORK)才能真正写入数据库并生效。 这是 SAP 事务处理机制的核心原则。

延申

一、创建测试序列的方法

在SE37界面,点击功能模块>执行>测试序列

点击测试序列,在弹框中输入函数名称,这里我是测试了BAPI和COMMIT WORK,我的界面如下:

完成后打勾就可以在BAPI调用成功后,进行COMMIT WORK提交了

二、理解 BAPI 的行为

务必查阅 BAPI 的文档(在 SE37 的 Documentation 标签页)。很多创建/更改数据的 BAPI 都需要显式提交。

http://www.dtcms.com/a/302221.html

相关文章:

  • 数据库简介
  • layui-vue 入驻 GitCode 平台:让前端开发更简单优雅
  • 【Oracle】ORACLE-ASM安装
  • vue-grid-layout元素交换位置及大小
  • Python Pandas.merge函数解析与实战教程
  • 【数学建模论文学习笔记】基于历史数据的蔬菜类商品定价与补货决策模型
  • Java从入门到精通!第十八天(JDK17安装以及网络编程) 完结篇!!!
  • 7.29 技巧|
  • 【数据库】使用Sql Server将分组后指定字段的行数据转为一个字段显示,并且以逗号隔开每个值,收藏不迷路
  • C# 接口(interface 定义接口的关键字)
  • JVM 垃圾回收机制全景解析:从对象回收到收集算法
  • Spring Boot日志开发实战手册:集成/输出/级别控制/持久化精要
  • MySQL 锁机制 15 连问 · 面试速答版
  • openeuler24.03部署k8s1.32.7集群(一主两从)
  • C primer plus (第六版)第九章 编程练习第6题
  • 基于YOLO11的电梯电瓶车检测系统:让电梯更安全
  • Redis反弹Shell
  • 《Java 程序设计》第 8 章 - Java 常用核心类详解
  • 安装研华板卡驱动
  • 重庆地区通信安全员考试题库及答案
  • tsc命令深入全面讲解
  • 零基础学习性能测试第六章:性能难点-Jmeter文件上传场景压测
  • 【智慧物联网平台】编译jar环境 Linux 系统编译IOT物联网——仙盟创梦IDE
  • React Immer 不可变数据结构的处理
  • Jmeter 性能测试监控之ServerAgent
  • Jmeter的元件使用介绍:(九)监听器详解
  • 10、Docker Compose 安装 MySQL
  • Redis数据量过大的隐患:查询会变慢吗?如何避免?
  • CacheGen:用于快速大语言模型推理服务的 KV 缓存压缩与流式传输
  • 【linux】高可用集群Keepalived