Every ABAP programmer knows the commands COMMIT WORK and ROLLBACK WORK, so everyone should be able to answer the following question:
“Do behave COMMIT WORK and ROLLBACK WORK different if you look at lock objects?”
I guess that most ABAP programmers will answer something like “There is no difference in the behaviour. After each one of the commands SAP locks are gone.” But it is true?
Let’s take a look at the lock object EBU_PARTNR that performs a write lock on the table BUT000 and locks a certain business partner. So please run following code an look at transaction SM12 during the waiting time:
CALL FUNCTION 'ENQUEUE_EBU_PARTNR'
EXPORTING
* MODE_BUT000 = 'E'
* CLIENT = SY-MANDT
partner = '1234'
* X_PARTNER = ' '
* _SCOPE = '2'
* _WAIT = ' '
* _COLLECT = ' '
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
ASSERT sy-subrc = 0.
ROLLBACK WORK.
WAIT UP TO 20 SECONDS.
If you run this code it behaves as expected: After ROLLBACK WORK the lock is deleted in SM12. But now run following code:
CALL FUNCTION 'ENQUEUE_EBU_PARTNR'
EXPORTING
* MODE_BUT000 = 'E'
* CLIENT = SY-MANDT
partner = '1234'
* X_PARTNER = ' '
* _SCOPE = '2'
* _WAIT = ' '
* _COLLECT = ' '
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
ASSERT sy-subrc = 0.
COMMIT WORK.
WAIT UP TO 20 SECONDS.
I guess you will be surprised: The lock object still exists after COMMIT WORK and vanishes after 20 seconds of waiting time. Do you know why? Here is a hint for solution:
CALL FUNCTION 'ENQUEUE_EBU_PARTNR'
EXPORTING
* MODE_BUT000 = 'E'
* CLIENT = SY-MANDT
partner = '1234'
* X_PARTNER = ' '
* _SCOPE = '2'
* _WAIT = ' '
* _COLLECT = ' '
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
ASSERT sy-subrc = 0.
DATA dummy TYPE sbook.
CALL FUNCTION 'SAPBC_FLBOOKING_UPDATE' IN UPDATE TASK
EXPORTING
lv_sbook = dummy.
COMMIT WORK.
WAIT UP TO 20 SECONDS.
Now the lock object is deleted after COMMIT WORK – but why? The update module SASAPBC_FLBOOKING_UPDATE inserts an empty row in the SBOOK table of the SAP flight data model. But why does this change the behaviour of COMMIT WORK? The reason is explained in SAP library if you search for the _scope parameter: “The default value 2 of the _scope paramter of the function module ENQUEUE_EBU_PARTNR means that the lock belongs to the update owner (owner_2) only. Therefore, the update inherits the lock when CALL FUNCTION ‘…‘ IN UPDATE TASK and COMMIT WORK are called. The lock is released when the update transaction is complete. You can release the lock before it is transferred to the update using ROLLBACK WORK. COMMIT WORK has no effect, unless CALL FUNCTION ‘…‘ IN UPDATE TASK has been called.”
The Solution
The last sentence explains the behaviour. If we perform database updates directly as above without using update modules (or services like object services that use them within the framework) than it is likely that after a COMMIT WORK locks still exists.
What can we learn?
This can lead to an unexpected behaviour of our programs. Just think a report that locks a certain row of a table, than performs an update and after 10.000 of those operations does a COMMIT WORK to save a bulk of changes to the database and then works on the next 10.000 items and so. If we don’t use update modules for database changes the lock objects still exists and will vanish not until end of the report – and this could be much too late.
To overcome this problem we should use update modules or should call function modules that do a dequeue and remove the locks.
And this is the problem: In my opinion COMMIT WORK shouldn’t make any assuptions on the specific locking-parameters and whether there are updates functions modules or not. This gets even more important if you want to create software that can be enhanced.
Cheers,
Tobias
COMMIT WORK. “Here the lock remains
WAIT UP TO 20 SECONDS. “Watch out in se12. The lock still exists!
* After 20 seconds the report is over and with its end the lock vanishes.
The putpose of teh WAIT command is to show that in some cases COMMIT WORK doesn’t remove the locks.
Again please excuse me if my understanding of ABAP is wrong but it seems to me that the code below should retain the lock for 20 seconds, not the one above.
Maybe you just switched two codes by mistake.
I.E. function module CALL FUNCTION ‘BAPI_MATERIAL_MAINTAINDATA_RT’ a bunch of enqueue locks are set, then the update is prepared and in case of changes the respective update modules are called. But if no changes are determined, the update modulesare not called and the locks remain set even after commit work.
There is a SAP note that adds a call to FM ‘MATERiAL_UPDATE_DUMMY’ (or comparable name) that is called IN UPDATE TASK an will trigger the release of all locks set with SCOPE = 2 wnen triggered by COMMIT WORK.
This means: You have to call at least one FM IN UPDATE TASK. Otherwise your locks are not released.
Regards,
Clemens