Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
gaurav_sharan
Explorer

1.    Objective


Objective of this document is to explain how to create custom lock/unlock action in case you are using legacy DAC. In my previous blog I have explain how to configure BOPF using Legacy tables. Refer to below link for more details on BOPF: Using Non-UUIDs (DB_KEY) keys DB tables

https://blogs.sap.com/2018/06/07/bopf-using-non-uuids-db_key-keys-tables/

2.    Why do we need Custom Lock/Unlock Action for Legacy DAC


The standard lock action will acquire a lock based on the instance UUID. Since the transient keys used by the legacy DAC start counting from ‘1’ for each session, it is very likely to experience locking issues. You can check in SM12 if the lock argument shows such a transient key instead of a proper UUID.


3.    How to Implement Custom Lock/Unlock Action


Implementation of Custom Lock/unlock action for legacy DAC requires the following steps:

3.1  BOPF Configuration


BOPF frameworks handles the enqueue and dequeue as well as lock-result implicitly at runtime. Changing the locking options is not supported by SAP, For more details you can refer to below link

https://blogs.sap.com/2015/07/21/abap-to-the-future-my-version-of-the-bopf-chapters-part-3/

If you just need to change Lock/Unlock configuration for Legacy DAC there should not be any issues. You have to make sure no other fields should be changed. For a developer it won’t be difficult to find a way to replace default locking/unlocking implementing Class /BOBF/CL_LIB_A_LOCK.

3.1.1        Enable visibility of Technical Entities


By default, Lock/Unlock Actions are not visible in the transaction Code /BOBF/CONF_UI. You can enable visibility of the technical entities responsible for locking in the display-options (Utilities -> Settings):


3.1.2        Change Implementing Class /BOBF/CL_LIB_A_LOCK


Click on the ROOT Node under then Node Elements then expand ACTION folder. You would be able to find LOCK_ROOT & UNLOCK_ROOT actions. Taking example from my previous blog, see below screenshot of default LOCK_ROOT and UNLOCK_ROOT action implementing class. You need to change configuration and add a custom class.





Configure same custom class for UNLOCK_ROOT.

 

3.2  Coding


Now you need to write your own custom Enqueue/Dequeue logic in the custom class. Custom Logic should be written inside method EXECUTE only.


3.2.1 Sample Code


Taking example from my previous blog BOPF: Using Non-UUIDs (DB_KEY) keys DB tables

https://blogs.sap.com/2018/06/07/bopf-using-non-uuids-db_key-keys-tables/

Locking is done for two custom field Quota Number and company code instead of Transient keys. The following steps provide example codes with step by step approach for enqueue dequeue call.

Step 1: check edit mode is correct else raise exception using BOPF framework
    DATA lr_parameter     TYPE REF TO /bobf/s_frw_lock_parameters.
DATA ls_location TYPE /bobf/s_frw_location.
DATA lr_cm TYPE REF TO /bobf/cm_lib.
DATA ls_key TYPE /bobf/s_frw_key.

lr_parameter ?= is_parameters.

* check lock mode
IF lr_parameter->edit_mode <> /bobf/if_conf_c=>sc_edit_exclusive AND
lr_parameter->edit_mode <> /bobf/if_conf_c=>sc_edit_shared AND
lr_parameter->edit_mode <> /bobf/if_conf_c=>sc_edit_optimistic AND
lr_parameter->edit_mode <> /bobf/if_conf_c=>sc_edit_promote AND
lr_parameter->edit_mode <> /bobf/if_conf_c=>sc_edit_check_optimistic.

eo_message = /bobf/cl_frw_factory=>get_message( ).
ls_location-node_key = is_ctx-node_key.
LOOP AT it_key INTO ls_key.
ls_location-key = ls_key-key.
CREATE OBJECT lr_cm
EXPORTING
textid = /bobf/cm_lib=>invalid_lock_mode
severity = /bobf/cm_frw=>co_severity_error
ms_origin_location = ls_location.
eo_message->add_cm( lr_cm ).
ENDLOOP.
et_failed_key = it_key.
RETURN.
ENDIF.

 

Step 2:  Based on Action Category Implement Lock and Unlock
IF is_ctx-act_cat = /bobf/if_conf_c=>sc_action_lock.
lock( EXPORTING is_ctx = is_ctx
it_key = it_key
is_parameters = lr_parameter->*
IMPORTING et_failed_key = et_failed_key
er_message = eo_message ).
ELSE.
unlock( EXPORTING is_ctx = is_ctx
it_key = it_key
is_parameters = lr_parameter->*
IMPORTING er_message = eo_message ).
ENDIF.

Step 3: Determine Key from Transient Key GUID using Class /BOBF/CL_LIB_LEGACY_KEY

 
FIELD-SYMBOLS: <fs_bukrs>   TYPE bukrs,
<fs_quotano> TYPE /bsk/quotano.
DATA ls_location TYPE /bobf/s_frw_location.
DATA lr_cm TYPE REF TO /bobf/cm_lib.
DATA: lt_legacy_key TYPE Ztt_k_db_key.”Legacy DAC Key (used in alternative root key)
DATA: lv_user TYPE syuname.

ls_location-node_key = is_ctx-node_key.
"Prepare Legacy key
/bobf/cl_lib_legacy_key=>get_instance( is_ctx-bo_key )->convert_bopf_to_legacy_keys(
EXPORTING
iv_node_key = is_ctx-node_key " Key of BOPF node
it_bopf_key = it_key " BOPF keys to convert
IMPORTING
et_legacy_key = lt_legacy_key " Resulting legacy keys
).
er_message = /bobf/cl_frw_factory=>get_message( ).

Step 4: Call Enqueue & Dequeue using Legacy Keys (for Example Company Code, Quota number)
    "Lock
LOOP AT lt_legacy_key ASSIGNING FIELD-SYMBOL(<fs_legacy_key>).
"Enqueue
TRY.
call_enqueue( EXPORTING iv_bukrs = <fs_legacy_key>-bukrs iv_quotano = <fs_legacy_key>-quotano ).
CATCH /bsk/cx_dsd_exceptions INTO DATA(lr_exception).
CLEAR: lv_user.
lv_user = lr_exception->if_t100_dyn_msg~msgv1.
"Raise
CREATE OBJECT lr_cm
EXPORTING
textid = /bobf/cm_lib=>modify_foreign_lock
severity = /bobf/cm_frw=>co_severity_error
ms_origin_location = ls_location
symptom = /bobf/if_frw_message_symptoms=>co_foreign_lock
mv_user = lv_user.
er_message->add_cm( lr_cm ).
"fill failed key
et_failed_key = it_key.
ENDTRY.
ENDLOOP.

Step 5: Enqueue Method

 
METHOD call_enqueue.
CALL FUNCTION 'ENQUEUE_ZE_TQUOTAH'
EXPORTING
* MODE_ZTQUOTAH = 'E'
* MANDT = SY-MANDT
bukrs = iv_bukrs
quotano = iv_quotano
* X_BUKRS = ' '
* X_QUOTANO = ' '
* _SCOPE = '2'
* _WAIT = ' '
* _COLLECT = ' '
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
" Raise exception
RAISE EXCEPTION TYPE zcx_dsd_exceptions
MESSAGE ID sy-msgid
TYPE sy-msgty
NUMBER sy-msgno
WITH sy-msgv1
sy-msgv2
sy-msgv3
sy-msgv4.
ENDIF.

ENDMETHOD.

Step 6: Unlock Method

 
METHOD unlock.
DATA: lt_legacy_key TYPE ztt_k_db_key.

"Prepare Legacy key
/bobf/cl_lib_legacy_key=>get_instance( is_ctx-bo_key )->convert_bopf_to_legacy_keys(
EXPORTING
iv_node_key = is_ctx-node_key " Key of BOPF node
it_bopf_key = it_key " BOPF keys to convert
IMPORTING
et_legacy_key = lt_legacy_key " Resulting legacy keys
).
"Lock
LOOP AT lt_legacy_key ASSIGNING FIELD-SYMBOL(<fs_legacy_key>).
"Dequeue
call_dequeue( EXPORTING iv_bukrs = <fs_legacy_key>-bukrs iv_quotano = <fs_legacy_key>-quotano ).
ENDLOOP.

ENDMETHOD.

Step 7: Dequeue Method

 
METHOD call_dequeue.
CALL FUNCTION 'DEQUEUE_ZE_TQUOTAH'
EXPORTING
* MODE_ZTQUOTAH = 'E'
* MANDT = SY-MANDT
bukrs = iv_bukrs
quotano = iv_quotano
* X_BUKRS = ' '
* X_QUOTANO = ' '
* _SCOPE = '3'
* _SYNCHRON = ' '
* _COLLECT = ' '
.

ENDMETHOD.
4 Comments