点击蓝字 关注我们
一
问题的发现
最近发现自动过账程序表中记录的单据过账状态与单据的实际过账状态不一致.
自动过账程序根据写入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 以确保更新一致.
THE
END
约定
如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.
(如果你真的喜欢这篇文章,请记得回来打个赏,作为支持我继续下去的动力,这是一个正反馈过程. 越多的人打赏,作者越有动力分享,读者就能享受更多的福利.毕竟打赏的金额富不了我,穷不了你,却能支持这个公众号长久发文.)
公众号 : syjf1976_abap
ABAP开发技巧
微信号 : 392077
公众号主群加入受限, 请扫码加入副群后,向管理员申请加入主群