To save external systems each having to define their own data, predefined buffering mechanisms should be implemented in all write BAPIs (i.e. BAPIs that create and change data).
For SAP internal use this is particularly relevant for BAPIs developed as of Release 4.6A. If you want to implement a buffer for BAPIs in an earlier release, you should first contact a colleague at the BFA AG.
For BAPIs standard SAP System mechanisms can be used to buffer application data. Data to be created or changed by a BAPI is not created in the update buffer, it is first collected in the buffer of the BAPI function module group. Then the whole buffer is updated at a specified time.
This has the following advantages:
· Improvement in performance of the whole system.
The updating of individual operations is delayed and they can all be updated together. Techniques such as "array insert" improve system performance. If buffering is not used, each change must be updated separately.
· Several changes to an application instance
With the first change the data is read from the database into the buffer and the change is made in the buffer. With the next change, the system recognizes that the data already exists in the buffer and also makes the change in the buffer. If buffering is not used, the first change would have to be updated before a second change could be made.
· Use for transferring data en masse
BAPIs with buffering are especially suited in situations where mass data is exchanged between systems via Application Link Enabling (ALE).
The buffering mechanism enables application instances to be processed separately in the ALE layer, while still enabling the instances to be updated together. Unlike multiple BAPIs, such as, SaveReplicaMultiple(), this procedure allows error handling of individual instances.
The Transaction Model for BAPIs Without Commit in use since Release 4.0 can be enhanced on the basis of these advantages:
· Within one Logical Unit of Work (LUW) several changes or detailed changes can be carried out for one instance.
· All changes (to one or more instances) are updated together by the BAPI BapiService.TransactionCommit().
This graphic shows the transaction model for BAPIs without buffering:
This graphic shows the transaction model for BAPIs with buffering:
The buffering mechanism for BAPIs must be implicit, that is, the caller must not have to control the buffering. A calling program must be able to use, for example, a Create() or Change() BAPI with buffering as well as it can use a BAPI without buffering. The buffer is updated implicitly in the SAP System.
If buffering has been implemented for a business object type, all write BAPIs of this business object type must also be implemented with buffering.
If write BAPIs with buffering have been implemented for a business object type, this affects the read BAPIs of this object type. Refer to the information in the Activities section below.
For BAPIs with buffering, in addition to the standard guidelines, the following implementation steps and characteristics described below are required.
As BAPIs with buffering can only create or change instances in the buffer, you have to provide one or more function modules to carry out the final update of the buffer contents. These update modules transfer the entire contents of the buffer to the update program.
These function modules should not be implemented as BAPIs, as these are only used in the system in which the buffer is also used.
The naming convention for these function modules is:
<Business object name>_SAVEBUFFER.
Exceptions must not be defined for the update modules, as these are not run until the end of the program, when error handling is no longer possible (see Special Characteristics below).
To ensure that the buffer is empty at the start of a transaction, you must provide a function module that deletes the contents of the buffer. This delete function module deletes the entire contents of the buffer and removes any locks on the instances. Neither should you implement this function module as a BAPI, because it is only used in the system in which the buffer is also used.
The naming convention for this function module is:
<Business object name>_CLEARBUFFER.
BAPIs with buffering need to have special characteristics. For example, these BAPIs must be able to deal with errors because a caller cannot reprocess data in the buffer. As data is buffered implicitly, no administration BAPIs are provided for callers.
A BAPI with buffering must carry out all the processing steps, except for updating. The consistency of all instances created or changed in the buffer must be guaranteed by the application.
This means that:
· Only operations that can be updated with consistency guaranteed can be carried out in the buffer. The update module itself cannot perform consistency checks.
· All other steps required before updating, such as assigning numbers or creating application blocks, must be carried out before calling the update module.
· For operations that cannot be updated consistently, no action can take place. In these cases the error situation must be reported in the BAPI return parameter.
After the buffer operations have been successfully carried out, using the command
PERFORM <routine> ON COMMIT
call a form routine <routine> which then calls the update module(s).
The update modules must be called using the command
CALL <Business object name>_SAVEBUFFER IN UPDATE TASK
to flag the execution in the update program.
By adding 'ON COMMIT' to the command PERFORM <routine> ON COMMIT, updating is not carried out immediately, it is carried out in the next COMMIT WORK. This way any number of BAPI calls can be collected together. The final COMMIT WORK command that is executed via the BAPI BapiService.TransactionCommit(), executes the form routine and also each update module once only. For this reason error handling cannot be performed in this form routine nor in the function module.
At the start of each LUW the buffer must be empty. Any instances that may exist in the buffer, which were updated in an earlier LUW, are no longer blocked and may be older than the versions in the database. If this instance is updated again, inconsistencies would result.
At the end of each LUW, the buffer contents must be deleted by calling the delete module. This can only be done by the BAPIs BapiService.TransactionCommit() andBapiService.TransactionRollback(). To supply these BAPIs with the necessary information, BAPIs with buffering must subscribe their delete module for the BAPI BapiService.TransactionCommit() or BapiService.TransactionRollback().
The delete module is subscribed by calling the central function module BUFFER_SUBSCRIBE_FOR_REFRESH, whereby the parameter NAME_OF_DELETEFUNC must contain the name of the delete module.
BAPIs with buffering must not execute COMMIT WORK or ROLLBACK WORK commands.
Each BAPI with buffering must be explicitly documented as such.
Keep in mind the following important information about how write BAPIs with buffering interact with read BAPIs of the same business object.
If write BAPIs with buffering are implemented for the same business object type, read BAPIs are not allowed to use the buffer for the same business object type, so that data read from the database can be stored, thereby avoiding further database accesses.
As the imported data is not locked, the corresponding data in the buffer would become outdated over time. Subsequent read operations would first access the buffer and read the potentially out-of-date data, as data in the database can only be read, if this data is not in the buffer.
All instances created or changed by write BAPIs in the buffer are consistent. They can be used by other change BAPIs for further processing within the same LUW.
To guarantee the consistent behavior, all read BAPIs must handle existing instances that are in the buffer, and not yet in the database, as valid instances. Read BAPIs must be implemented in such a way that they first try to read an instance in the buffer and only start searching the database, if the instance is not found in the buffer.
A buffer instance is therefore "real" instance. For example, a BAPI ExistenceCheck() must search for the existence of an instance in the buffer also.
Each read BAPI that handles the buffering of corresponding write methods must be documented.