Many people continue using (or advising to use) COMMIT WORK after a call to a BAPI function module.
You must always call BAPI_TRANSACTION_COMMIT (not COMMIT WORK) if you have called at least one BAPI function module within the current LUW.
Here's why (inspired from this SDN thread):
- By simply looking at BAPI_TRANSACTION_COMMIT code, we see quickly what is different from COMMIT WORK. It calls BUFFER_REFRESH_ALL function module right after COMMIT WORK.
- So BAPI_TRANSACTION_COMMIT additionally refreshes a "BAPI buffer".
- Here is what BAPI buffer is for:
- Assuming your program calls BAPIs consecutively and use a COMMIT WORK/BAPI_TRANSACTION_COMMIT only at the end so that to commit all BAPI updates once (better performance).
- As you know, BAPIs need to check errors like data missing in database. For example, the second BAPI may have to check the existence of data written by the previously called BAPI. The data doesn't exist in database yet, but as it knows it will be written later at COMMIT WORK time, it uses a buffer (memory) to store this information, so that no error is raised.
- Let's suppose the update during the COMMIT WORK fails (for any reason), the data is not written to database. If you have not refreshed the buffer using BAPI_TRANSACTION_COMMIT, the next BAPI calls will consider that some data will exist later, that is wrong.
The same kind of logic applies to the rollback: you must call BAPI_TRANSACTION_ROLLBACK instead of ROLLBACK WORK. It will empty the BAPI buffer too. Here's why:
- If you rollback the first BAPI using ROLLBACK WORK statement, you must absolutely refresh the buffer, otherwise the next BAPI could think that the data will exist and would attempt erroneously to write data.
All that is probably better explained in SAP Library documentation about BAPI buffer
To test a BAPI, you need to use a test sequence in SE37, for calling BAPI_TRANSACTION_COMMIT. See SDN wiki - Function Module Test Sequence.
- SAP library documentation about BAPI template code shows why buffers were initially required at an older time: as only PERFORM ON COMMIT was available (CALL FUNCTION IN UPDATE TASK did not exist yet), all data had to be retained in memory (because the form is called once though registered several times).
- Now, as only CALL FUNCTION IN UPDATE TASK should be used, it makes obsolete this documentation and the need for storing data in memory. But buffer is still in use as I explained above.