Attila, S/4HANA, BTP Fullstack Developer (EN, DE, HU)
Locking in ABAP on BTP
The most important thing here is to know the factory class cl_abap_lock_object_factory, which creates You an instance of the lock implementing the interface if_abap_lock_object, just provide the Lock Object name.
Use method enqueue/dequeue to lock the required record(s) providing a name-value pair table passing the field names and the corresponding value.
In case invalid parameters are provided, cx_abap_lock_failure is triggered.
If someone else is locking the record(s) already, You get exception cx_abap_foreign_lock, where the user_name attribute holds the guilty user name :).
TRY.
"Get instance of lock object
DATA(lock) = cl_abap_lock_object_factory=>get_instance( iv_name = 'EZ_ZPMMNRQ' ).
"Enqueue(lock) the record / group of records
lock->enqueue(
it_parameter = VALUE #( ( name = 'PLANT' value = REF #( 'DE82' ) ) )
).
"lock error
CATCH cx_abap_lock_failure INTO DATA(ex_lock_failure).
"Depends on implementation if You need to let it dump
RAISE SHORTDUMP ex_lock_failure.
"foreign lock
CATCH cx_abap_foreign_lock INTO DATA(ex_foreign_lock).
"This user is locking already
DATA(iam_locking_it) = ex_foreign_lock->user_name.
ENDTRY.
Interesting facts
Some part of the factory is implemented inside with TEST-SEAM, whether You are allowed to use that lock object. It means released or not in cloud development.
METHOD whitelist_check.
"check if caller is allowed to use the object
TRY.
DATA lt_objects_not_to_be_used TYPE if_ars_abap_object_check=>ty_gts_object_not_to_be_used.
TEST-SEAM ars_generic_call_check.
lt_objects_not_to_be_used = cl_ars_generic_call_check=>get_instance( )->check( "Perform object restriction check
iv_api_name = 'CL_ABAP_LOCK_OBJECT_FACTORY'
it_used_objects = VALUE #( ( object-type = 'ENQU' object-name = iv_name ) ) ).
END-TEST-SEAM.
IF lt_objects_not_to_be_used IS NOT INITIAL.
RAISE EXCEPTION TYPE cx_abap_lock_failure
EXPORTING
textid = cx_abap_lock_failure=>object_not_to_be_used
object_name = |{ iv_name }|
object_type_text = |{ 'lock object'(001) }|.
ENDIF.
CATCH cx_ars_abap_object_check INTO DATA(lx_exc).
RAISE EXCEPTION TYPE cx_abap_lock_failure
EXPORTING
previous = lx_exc.
ENDTRY.
ENDMETHOD.
Another interesting thing, that the lock object implementation is a local class within the factory class implementing the global interface if_abap_lock_object. Here You at which place the exception is triggered, when the record(s) is/are locked already.



