我有一个C#web应用程序,它在ASP.net网站中的一个函数处调用多个BAPI和存储过程。如果函数中的一个方法失败,我需要回滚在web上调用的函数上执行的所有bapi。
在SQL中,我调用
SqlTransaction transaction = connectionsql.BeginTransaction();
...
transaction.Rollback();
如果其中一个方法失败,则在c#代码上执行。(这可以用于sql回滚)
但对于SAP BAPI,即使我在C#catch语句上调用BAPI_TRANSACTION_ROLLBACK,更改仍然存在。(回滚不成功)
仅供参考,在我的BAPI函数中,我使用CSAP_MAT_BOM_MAINTAIN来更新BOM表信息。
有没有什么方法可以在我的C#代码中为SAP BAPI函数执行类似sql事务的回滚,并在web捕获异常时回滚在C#上运行的所有BAPI?
首先必须检查BAPI是否包含COMMIT WORK
语句。当然,这会干扰您的交易处理。
接下来,您必须注意正确的会话处理。您已经在BAPI调用周围放置了以下函数调用。
RfcSessionManager.BeginContext()
和
RfcSessionManager.EndContext()
如果没有这个上下文括号,每个BAPI调用都将在不同的上下文中执行。
你的想法是正确的。理想情况下,您应该能够从ASP.net代码中执行以下操作:
- 调用BAPI 1
- 调用BAPI 2
- 等等
- 如果成功,则调用
BAPI_TRANSACTION_COMMIT
;如果错误,则调用BAPI_TRANSACTION_ROLLBACK
不幸的是,如果BAPI本身包含COMMIT
(许多旧的和非BAPI功能模块都包含),那么ROLLBACK
将为时已晚——数据将已经提交。
在您的情况下,功能模块CSAP_MAT_BOM_MAINTAIN
包含一个FL_COMMIT_AND_WAIT
参数,但这只会影响COMMIT
是否等待(无论哪种方式,提交都会发生)。然而,可能有一个变通方法:在我的系统中的子程序CSAP_MAIN_INIT
(包括LCSAPF01
)中,有以下代码行:
import flg_no_commit_work from memory id 'CS_CSAP'.
该标志(flg_no_commit_work
)随后被传递到对功能模块CS_DI_BOM_VB
的调用中(从CSAP_MAT_BOM_MAINTAIN
调用),如果它被设置,则不执行COMMIT
。也许可以尝试通过EXPORT TO MEMORY
设置该标志,看看这是否有帮助。当然,这是未记录的,SAP也不支持,但它很可能有效。。。