MDG – How to prevent “material locked” error at activation
Sometimes when MDG-M process reach activation phase the material might get locked by another user and the activation fails:
This can happen either when there is another parallel process created for the material and someone opens dialog task in edit mode or – in case of co-deployment scenario – one of the multiple “material locking transactions” is being run.
Manual solution for such incident is to restart the failed activation task by administrator. Even if this does not happen often, once occurred, it usually takes time for detection and fixing.
Below I’m describing approach which can be used to avoid such problem. The solution is based on Rule Based Workflow WS60800086, but it can be also applied in other MDG workflows and for other master data objects (not only materials).
The activation fails because the processed material can’t be exclusively locked, so just before activation we should try to set the same lock in our custom code; if succeeded, we release the lock and continue with the activation. In case of locking failure we should wait some amount of time and try again.
Fortunately, SAP Business Workflow has a nice feature for restarting failed tasks (recoverable errors, details here). In short, if in workflow task a special class exception is raised, then the task will be automatically restarted by scheduled job running program RSWWERRE – usually there are 3 attempts every 20 minutes (depends on configuration). The “special class exception” means here class inheriting from CX_BO_TEMPORARY.
The implementation can be done at least in two ways:
Enhance standard Activation method (CL_USMD_WF_BO_SERVICE->ACTIVATE_CREQUEST) or add new background processing activities just before the Activation in the workflow. Below I’m describing the second approach.
If your MDG processes are based on standard workflow WS60800086 copy it to new one and add new activity right before Activation activity:
Above, it is added just before “Activation bypassing snapshot”, but if you use in your MDG workflows both activation types add the activities in both places pointed above (using the same task in both).
Configuration of the activity and task can look like this:
The new class ZCL_USMD_WF_SWW must implement interface IF_WORKFLOW, information how to implement methods of the interface you can find in many tutorials in the Internet or just check how it was done in standard class CL_USMD_WF_SWW.
The CHECK_OBJECT_LOCKS method should be declared like below:
methods CHECK_OBJECT_LOCKS importing !IV_CR_NUMBER type USMD_CREQUEST raising CX_BO_TEMPORARY.
and contain code similar to this:
DATA: lo_gov_api TYPE REF TO cl_usmd_gov_api, lv_rise_temporary_error TYPE abap_bool VALUE abap_false. cl_usmd_crequest_util=>get_model_by_cr( EXPORTING i_crequest = iv_cr_number IMPORTING e_model = DATA(lv_model) ). CASE lv_model. WHEN 'MM'. DATA(lt_matnr) = zcl_mdgm_tools=>get_cr_materials( iv_cr_number = iv_cr_number ). TRY. lo_gov_api ?= cl_usmd_gov_api=>get_instance( iv_model_name = lv_model ). lo_gov_api->enqueue_crequest( iv_crequest_id = iv_cr_number ). lo_gov_api->enqueue_entity( iv_crequest_id = iv_cr_number iv_entity_name = if_mdg_bs_mat_gen_c=>gc_entity_material it_data = lt_matnr ). CATCH cx_usmd_gov_api INTO lr_ex_gov_api. lv_rise_temporary_error = abap_true. ENDTRY. lo_gov_api->dequeue_entity( iv_crequest_id = iv_cr_number iv_entity_name = if_mdg_bs_mat_gen_c=>gc_entity_material it_data = lt_matnr ). lo_gov_api->dequeue_crequest( iv_crequest_id = iv_cr_number ). ENDCASE. IF lv_rise_temporary_error EQ abap_true. RAISE EXCEPTION TYPE cx_bo_temporary. ENDIF.
Of course you can create own exception class to pass information about locking user and material (how-to guide here). You should also remember to assign the new copied workflow in configuration of your MDG Change Requests.
The solution described here will not prevent the locking problem in 100% cases, there still may happen that user who opens transaction in edit mode goes for some long meeting – after 3 attempts of activation the workflow will end up finally in error state – but in such case we should rather think about fixing the user, not the sytem 😉