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.pswp.cn/web/44473.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/44473.shtml
英文地址,請注明出處:http://en.pswp.cn/web/44473.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

編譯打包自己的云手機(redroid)鏡像

前言 香橙派上跑云手機可以看之前的文章&#xff1a; 香橙派5plus上跑云手機方案一 redroid(帶硬件加速)香橙派5plus上跑云手機方案二 waydroid 還有一個cuttlefish方案沒說&#xff0c;后面再研究&#xff0c;cuttlefish的優勢在于可以自定義內核且selinux是開啟的&#xf…

vue3下載base64文件

如果后端明確告訴你返回的是base64&#xff0c;那請求頭就不用帶responseType: “blob”,和普通的接口一樣發送就行 await materialsFile({ id: proxy.$route.query.id }).then((res) > {if (res) {// atob先解碼base64數據const raw window.atob(res.data);// 獲取解碼后…

vscode 遠程開發

目錄 vscode 遠程連接 選擇 Python 環境 vscode 遠程連接 按 CtrlShiftP 打開命令面板。輸入并選擇 Remote-SSH: Open SSH Configuration File...。選擇 ~/.ssh/config 文件&#xff08;如果有多個選項&#xff09;。在打開的文件中添加或修改你的 SSH 配置。 這個可以右鍵…

Jupyter Notebook基礎:用IPython實現動態編程

Jupyter Notebook基礎&#xff1a;用IPython實現動態編程 1. 引言 Jupyter Notebook是一個基于Web的交互式計算環境&#xff0c;允許用戶創建和共享包含實時代碼、方程式、可視化和文本敘述的文檔。它廣泛應用于數據清洗與轉換、數值模擬、統計建模、機器學習以及其他數據科學…

開放開源開先河(一)

2022年7月28日&#xff0c;以“軟件定義世界 開源共筑未來”為主題的全球數字經濟大會開放原子開源峰會在北京開幕&#xff0c;承辦主峰會和為捐贈人進行授牌儀式的開放原子開源基金會再次進入公眾視野。基金會秘書長孫文龍從匯聚全球產業鏈開源力量、核心鏈接能力、開發者分享…

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…

git reset hard和soft的使用和區別

在Git中&#xff0c;git reset命令用于撤銷提交、回溯版本和調整工作目錄或暫存區狀態&#xff0c;而不是gitrestore。git reset主要有三種模式&#xff1a;--soft、--mixed&#xff08;默認&#xff09;和--hard。以下是關于--hard和--soft兩種模式的使用方法和區別的詳細解釋…

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;”無疑是這股浪潮中的璀璨明星。它利用先進的人工智能技術…

記錄一次Android推流、錄像踩坑過程

背景&#xff1a; 按照需求&#xff0c;需要支持APP在手機息屏時進行推流、錄像。 技術要點&#xff1a; 1、手機在息屏時能夠打開camera獲取預覽數據 2、獲取預覽數據時進行編碼以及合成視頻 一、息屏時獲取camera預覽數據&#xff1a; ①Camera.setPreviewDisplay(SurfaceH…

通過 Azure OpenAI 服務使用 GPT-35-Turbo and GPT-4(win版)

官方文檔 Azure OpenAI 是微軟提供的一項云服務&#xff0c;旨在將 OpenAI 的先進人工智能模型與 Azure 的基礎設施和服務相結合。通過 Azure OpenAI&#xff0c;開發者和企業可以訪問 OpenAI 的各種模型&#xff0c;如 GPT-3、Codex 和 DALL-E 等&#xff0c;并將其集成到自己…

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;對于實現某個功能時&#xff0c;可以使用高級工具&#xff0c;也可以直接使用底層工具。這兩種方式運行的開銷差異稱為抽象損失。 二、線程管控 2.1 線程的基本控制 1. 創建線程 線程相關的管理函數和類在頭文件&#xff1a; #include <…

數據結構——線性表(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;秒 時間分界線可以由…

GIT相關操作,推送本地分支到遠程倉庫流程記錄學習

git流程 切換到源文件夾&#xff1a;cd 源文件夾克隆遠程倉庫&#xff1a;git clone [ssh]進入項目文件夾&#xff1a;cd .\project\查看本地分支&#xff1a;git branch獲取遠程倉庫更新&#xff0c;使遠程同步&#xff1a;git fetch查看所有分支&#xff08;包括遠程分支&am…

OJ-0712

示例1&#xff1a; input 8 123 124 125 121 119 122 126 123 output 1 2 6 5 5 6 0 0示例2&#xff1a; input 2 95 100 output 1 0示例3&#xff1a; input 2 100 95 output 0 1package com.wsdcode.od;import java.util.Scanner;public class Main {public static void m…

LabVIEW比例壓力控制閥自動測試系統

開發了一套基于LabVIEW編程和PLC控制的比例控制閥自動測試系統。該系統能夠實現共軌管穩定的超高壓供給&#xff0c;自動完成比例壓力控制閥的耐久測試、流量滯環測試及壓力-流量測試。該系統操作簡便&#xff0c;具有高精度和高可靠性&#xff0c;完全滿足企業對自動化測試的需…