函数(function) 用于将可能重复的程序,或者具有一定特殊性的程序功能,封装起来,写成一个子程序块,有输出和输入参数,方便以后使用时,直接调用。
RFC函数(Remote Function Call) :RFC函数,本质上也是一种函数,是一种可远程调用的函数。此类函数,可以被外部程序或者外部系统调用。也就是说,RFC函数,不仅可以被SAO系统的内部程序所直接调用,也可以被非SAP的外部系统调用
注意: RFC函数可以与外部系统进行接口,也就是说可以与外部系统进行数据交换,所以RFC函数,不仅可以理解为一种函数,也可以理解为一种数据通信协议。
BAPI (bsinesss application programming interfaces): 中文翻译为"业务应用编程接口"。 BAPI本质上也是一种RFC函数,或者说一种特殊的RFC函数。BAPI是SAP系统提供的,标准的,可用于在SAP系统中实现相关事务的RFC函数。也就是说,用户希望通过外部系统做操作,进而通过接口直接在SAP中创建订单等,就可以通过外部系统调用SAP的BAPI进行实现。
SAP系统本身就提供了大量的BAPI,比如 ,采购订单,销售订单,生产订单等的创建,更改,显示等
基于以上解释,我们可以简单理解函数,RFC 函数以及BAPI,在一定维度上,有定义的包含从属关系。
即 函数包括RFC函数包括BAPI
注意,这里的BAPI理解为项目中常用到的,SAP提供可用于外部调用的标准BAPI
BAPI创建步骤:
1.创建数据库表结构SE11
2.SE80创建函数组和函数,输入参数参考SE11创建的结构
3.SWO1创建BAPI对象,添加API方法 - SE80创建的函数
4.释放对象,SE37,SWO1.
再讲rollback之前先讲以下BAPI_TRANSACTION_COMMIT 以及commit work and wait.操作:
1.这两个语句都是数据的提交操作,但不同点是
BAPI_TRANSACTION_COMMIT 之后会执行一个buffer_refresh_all函数,也就是BAPI_TRANSACTION_COMMIT 函数在数据提交之后还有一个刷新 BAPI buffer 缓冲区的操作,这个操作可以避免多表写入时发生的错误,所以当我们要连续修改很多表且这些表又相互关联的时候最好使用 bapi_transaction_commit;
2 在一般情况下SAP数据提交都是异步操作,即如果没有主动同步提交数据的话,数据提交操作都是在程序执行完毕之后统一commit ,所以当我们后续代码如果需要依赖前面bapi 执行数据,就需要主动同步提交数据才行,同步提交时需要给BAPI_TRANSACTION_COMMIT提交函数加一个输入参数 wait = ‘X’, commit work语句后加一个 and wait 部分,表示同步提交,只有在数据提交完毕之后程序才接着往下执行。
然后我们讲一讲 BAPI_TRANSACTION_ROLLBACK 数据回滚的问题,
BAPI_TRANSACTION_ROLLBACK回滚操作会把上一次数据commit之后与这一次rollback之前的所有操作都回滚,这期间如果有做了写日志等操作,就需要在写日志完毕之后主动同步提交数据,从而避免被rollback掉。
SAP系统提供的BAPI参数结构有个特点:一般会将类似的字段放在同一个结构中,同时,还会存在一个与该结构名类似(后面以X结尾) 标识结构,该标识结构中的字段名与赋值的结构中的字段名一致,但是其字段类型只是一个长度为1的字符,用于表示某个字段的数据是否需要通过BAPI来变更
根据事务的ACID原则,一个独立的BAPI实现必须具有事务性,同时,BAPI事务模型还必须允许开发者在调用多个BAPI时可以将它们绑定到同一个LUW上。因此,如果同时调用几个BAPI,开发者需要在程序中进行事务控制,决定何时执行数据库提交或回滚操作: 而BAPI内部则通常不包含CMMIT WORK和 ROLLBACK WORK命令
操作多个BAPI时必须遵循以下原则:
操作多个BAPI时必须遵循以下原则:
如果有更新操作的BAPI,如创建、修改或删除一个业务对象实例,则对该实例进行另外的读取操作的BAPI只能访问上一个COMMIT WORK执行后的最新数据
在同一个LUW中,不能对同一个业务对象实例时行超过一次的更新操作。例如,不允许在一个LUW中创建一个新实例,随后就修改它。但可以创建多个相同的类型的不同实例
在BAPI内部,数据库更新操作必须通过同步或异步的更新过程实现(需使用 CALL FUNCTION update function IN update TASK的方式来更新数据库),因为否则可能出现不必要的数据库提交过程,从而破坏了BAPI调用的ACID原则。同样原因,BAPI内部也不能触发新的LUW,因而其内部程序代码中不能包含以下命令:
CALL TRANSACTION
SUBMIT REPORT
SUBMIT REPORT AND RETURN
COMMIT WORK
ROLLBACK WORK
因此,BAPI事务中的数据库提交和回滚必须在主调程序中通过调用SAP标准业务对象BapiService(业务对象类型为SAP0001)的BAPI方法BapiService.TransactionCommit(此BAPI方法实际上还是通过调用BAPI函数BAPI_TRANSACTION_COMMIT来实现的)和BapiService.TransactionRollback(此BAPI方法实际上还是通过调用BAPI函数BAPI_TRANSACTION_ROLLBACK来实现的)来完成
外部程序直接到调用BapiService.TransactionCommit方法,才会触发BAPI方法中的数据库提交
对于BAPI的操作都要用 BAPI_TRANSCTION_COMMIT 来提交的,在提交前,要根据BAPI函数的执行返回参数RETURN来判断函数是否执行成功(RETURN 中是否有E类消息),如果有错误消息则要用 BAPI_TRANSACTION_ROLLBACK取消所做的操作,而不是COMMIT WORK,如:
CALL FUNCTION ‘BAPI_FIXEDASSET_CHANGE’
…
IMPORTING
return = return.
IF return-type <> ‘S’.
CALL FUNCTION ‘BAPI_TRANSACTION_ROLLBACK’.
ELSE.
CALL FUNCTION ‘BAPI_TRANSACTION_COMMIT’
EXPORTING
wait = ‘X’.
ENDIF.
另外建议在调用BAPI_TRANSACTION_COMMIT函数进行提交BAPI操作时,加上wait参数,这样直到BAPI函数中的数据库操作提交数据库后,才去执行其后面的语句,这样后面程序依赖于此提交的数据时就不会出问题:
CALL FUNCTION ‘BAPI_TRANSACTION_COMMIT’
EXPORTING
wait = ‘X’.
WAIT为X时,会执行COMMIT WORK AND WAIT语句,否则执行COMMIT WORK语句