Good Practice:
Usage of COMMIT or the wrapper BAPI_TRANSACTION_COMMIT in User exit should be avoided, the reason you should not COMMIT WORK in a user exit is simply you have no idea what other database changes have already been done and what other database changes may follow after the user exit. If in one of the following steps a severe error is detected, all prior changes cannot be rolled back. COMMIT WORK means that all changes still in the rollback segment of the database will be applied and finalized to the database. The rollback segment will also be dumped that there is no chance to find out details about the changes.
Within your user-exit you have the option of:
· Doing DB update but don't commit them and when the overall transaction is committed
by the standard transaction then your updates will also be committed.
· Putting your updates into an IN UPDATE TASK function module or form routines called as PERFORM ... ON COMMIT or PERFORM ... ON ROLLBACK and calling this during the user-exit. It won't actually be executed until the main transaction calls the COMMIT WORK and then at that time it will be executed in an update process along with the other standard update functions as part of the transaction.
All function modules called IN UPDATE TASK will be executed in their own update process after COMMIT or DUMPED after rollback
All form routines called as PERFORM ... ON COMMIT or PERFORM ... ON ROLLBACK will be executed only after explicit COMMIT WORK or ROLLBACK WORK.
The addition 'AND WAIT' just means that the next program statement is not executed before all update processes started with COMMIT WORK have finished.
The general rule derived from this can be:
Never do a commit or rollback in a process which is called by another process. The only place for COMMIT or ROLLBACK is at the end of reports and transactions using CALL ... IN UPDATE TASK or PERFORM ... ON COMMIT - if you call any functions you should be aware that function modules may initiate update calls and/or form calls ...ON COMMIT/ROLLBACK. An explicit COMMIT WORK at the end of a process (or ROLLBACK WORK in case of error) will be OK.
Exception / Partial code commit in standard User-Exits:
Problem:
Sometimes we might have a scenario where we need to update the DB immediately before the calling program execution is completed.
For Example: I had a scenario, where the consignments stock needs to be updated using BAPI goods movement creation, so that the sales order line item is not rejected. Earlier Client used to check sales order with rejected stock and then regularize the stock in SAP using MIGO. But clients wants to code to check itself in the sales order for rejected quantity and update the stock in the SAP.
In this Regard, I had to use the /AFS/BAPI_GOODSMVT_CREATE, unless I commit this BAPI the stock won’t be updated in the SAP and in turn which will prevent the quantity in sales order from being rejected when ATP check is done. I need the FM to be committed immediately as a separate DB transaction from the main calling program
Solution:
The way to accomplish this is to put the updates and your commit work into a FM and mark the FM as RFC enabled (note, does not need to be Update enabled because this isn't an update task) . In the user-exit call the new FM with the addition “STARTING NEW TASK”
>CALL FUNCTION func STARTING NEW TASK task
> [DESTINATION {dest|{IN GROUP {group|DEFAULT}}}]
> parameter_list
> [{PERFORMING subr}|{CALLING meth} ON END OF TASK].
By doing this function call in a new task it is actually making an RFC to another process on one of the application servers and will be handled as a separate DB transaction from the main program.
Drawbacks:
Note, this is a very specific requirement because there is no roll-back possible for the code written inside the FM calling in the NEW TASK
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
2 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |