Business Scenario

Collision problems between loadings occurred, in our organization, every night and caused process chains to fail.

The collisions root cause is "Attribute Change Run" process was running for a specific Characteristic which is included in an InfoCube for which its "Cube Roll Up to BIA" process ran on the same time.

 

The Solution

The solution we came with was to implement a wait abap program which will be called by a process chain right before a problematic step.

It means that, for the scenario describe above, the wait program inserted before the "Attribute Change Run" in one chain to make sure the Roll Up to BIA chain isn't running, and before the "Cube Roll Up to BIA" in another chain to make sure that the Attribute Change Run chain isn't running.

The wait program checks whether the other is running or not. In case it is running, the program will wait for the seconds number which entered in the program parameter and then check again if the process chain is running. If the checked process chain isn't running, the current process chain will continue to run.

 

Process Chain with Attribute Change RunProcess Chain with Cube Roll Up to BIA
Before the "Attribute Change Run" step, call the wait program to check whether the Cube Roll Up process chain is runningBefore the "Cube Roll Up to BIA" step, call the wait program to check whether the Attribute Change Run process chain is running
Change Run PC.pngBIA PC.png
On the step marked in yellow, we check that the process chain on the right is not running nowOn the step marked in yellow, we check that the process chain on the left is not running now

 

 

Implementation Details

 

Step #1

Create a function which will get a process chain technical name and dates (as optional parameter). The function will retrieve the process chain logs and 'A' in the active status parameter if at least one of the process chains logs (according to the input parameters) is active.

 

Go to transaction SE37 and create a Function Module called "ZBW_GET_CHAIN_STATUS".

Description: Get the Process Chain Status

Define the function signature:


Parameter NameTyping
TypeDescriptionComments
ImportI_CHAIN_IDTYPERSPC_CHAINProcess Chain
ImportI_DATE_FROMTYPESYDATUM
Optional
ImportI_DATE_TOTYPESYDATUM
Optional
ExportE_ACTIVE_STATUSTYPERSPC_STATERetrieve 'A' if chain is activeOptional
TablesT_RSPCLOGCHAINLIKERSPCLOGCHAIN

Cross-Table Log ID / Chain ID

Optional
Exceptions

NO_DATA_FOUND



No data was found for selection
ExceptionsDATE_FROM_IS_NOT_
MAINTAINED


The I_FROM_DATE is not maintained while the I_TO_DATE is maintained.

 

Copy the function code:

 

FUNCTION zbw_get_chain_status.
 *"----------------------------------------------------------------------
 *"*"Local Interface:
 *"  IMPORTING
 *"     VALUE(I_CHAIN_ID) TYPE  RSPC_CHAIN
 *"     VALUE(I_DATE_FROM) TYPE  SYDATUM OPTIONAL
 *"     VALUE(I_DATE_TO) TYPE  SYDATUM OPTIONAL
 *"  EXPORTING
 *"     VALUE(E_ACTIVE_STATUS) TYPE  RSPC_STATE
 *"  TABLES
 *"      T_RSPCLOGCHAIN STRUCTURE  RSPCLOGCHAIN OPTIONAL
 *"  EXCEPTIONS
 *"      NO_DATA_FOUND
 *"      DATE_FROM_IS_NOT_MAINTAINED
 *"----------------------------------------------------------------------
 **** Get the statuses of a single process chain
   DATA: lt_date_range TYPE RANGE OF sydatum,
         ls_date_range LIKE LINE OF lt_date_range.
 **** Build a range for the optional i_datum parameter
   IF i_date_from IS NOT INITIAL AND
      i_date_to   IS NOT INITIAL.
     ls_date_range-sign = 'I'.
     ls_date_range-option = 'BT'.
     ls_date_range-low = i_date_from.
     ls_date_range-high = i_date_to.
   ELSEIF i_date_from IS NOT INITIAL AND
          i_date_to   IS INITIAL.
     ls_date_range-sign = 'I'.
     ls_date_range-option = 'EQ'.
     ls_date_range-low = i_date_from.
   ELSEIF  i_date_from IS INITIAL AND
           i_date_to   IS NOT INITIAL.
     RAISE date_from_is_not_maintained.
   ENDIF.
   APPEND ls_date_range TO lt_date_range.
 **** Select the process chain status data
   SELECT *
     FROM rspclogchain INTO TABLE t_rspclogchain
       WHERE chain_id = i_chain_id AND
             datum   IN lt_date_range
         ORDER BY datum DESCENDING zeit DESCENDING.
   IF sy-subrc <> 0.
     RAISE no_data_found.
   ENDIF.
 **** Check if the chain is running (status = A)
   READ TABLE t_rspclogchain TRANSPORTING NO FIELDS
     WITH KEY analyzed_status = 'A'.
   IF sy-subrc = 0.
     e_active_status = 'A'.
   ENDIF.
ENDFUNCTION.

 

Don't forget to activate the function.

 

Step #2

Create a program which will get a process chain technical name, number of wait iterations and number of seconds to wait. The program will check only for the current date if the process chain is in active status. In case it is, the program will wait the number of seconds entered as a parameter and will check again if the process chain is in an active status. Again, in case it is it will wait. When the process chain is not in active status the program will end successfully.

What happened if the entered process chain isn't ending and stuck in a active mode? the program will terminates itself with a failure message after it will complete number of the wait iterations which entered also as a parameter to the program.


Program Run TimeFinish Status of the program
Best case2 secondsSuccessfully
all others
Successfully
Worst case(No. of Times to Wait) x (Seconds to Wait)Failure with an error message

 

Go to transaction SE38 and create a program called "ZBW_WAIT_FOR_CHAIN_TO_FINISH".

Description: Gets chain name, in case its active waits for it to finish

Type: Executable program

 

Copy the program code:

 

*----------------------------------------------------------------------*
 * Report  ZBW_WAIT_FOR_CHAIN_TO_FINISH                                 *
 *----------------------------------------------------------------------*
 * Get process chain name, check whether it's active or not.
 * In case it is active, wait until it's finish.
 *----------------------------------------------------------------------*
 REPORT  zbw_wait_for_chain_to_finish.
 *======
 * Data
 *======
 *TYPES: BEGIN OF ty_chain_status,
 *        chain_name    TYPE rspc_chain,
 *        active_status TYPE rspc_state,
 *      END OF ty_chain_status.
 *
 *DATA: ls_chain_status    TYPE          ty_chain_status,
 *      lt_chain_status    TYPE TABLE OF ty_chain_status,
 DATA: lv_chain           TYPE rspc_chain,
       lv_active_status   TYPE rspc_state,
       lv_is_chain_active TYPE boolean,
 *      lv_is_error        TYPE boolean,
       lv_times_counter   TYPE i.
 *============
 * Parameters
 *============
 SELECT-OPTIONS: so_chain FOR lv_chain.
 PARAMETERS: p_sec   TYPE i,
             p_times TYPE i DEFAULT 1.
 *            p_fdate TYPE sy-datum,
 *            p_tdate TYPE sy-datum.
 *====================
 * Start-Of-Selection
 *====================
 START-OF-SELECTION.
   CLEAR: lv_times_counter.
 *===========
 * Wait Loop
 *===========
   DO.
 *   Check if one of the chains entered is in Active status
     CLEAR: lv_is_chain_active.
 *           lv_is_error.
 *===============
 *   Chains Loop
 *===============
     LOOP AT so_chain.
       CLEAR: lv_active_status.
       CALL FUNCTION 'ZBW_GET_CHAIN_STATUS'
         EXPORTING
           i_chain_id                  = so_chain-low
           i_date_from                 = sy-datum      " p_fdate
 *          i_date_to                   = p_tdate
         importing
           e_active_status             = lv_active_status
 *        tables
 *          t_rspclogchain              =
         exceptions
           no_data_found               = 1
           date_from_is_not_maintained = 2
           OTHERS                      = 3.
 *      IF ( sy-subrc = 2 ).
 *        lv_is_error = 'X'.
 *        EXIT.
 *      ENDIF.
 *    If chain is active mark it and stop checking
       IF ( lv_active_status = 'A' ).
         lv_is_chain_active = 'X'.
         EXIT.
       ENDIF.
     ENDLOOP.
 *   If an active chain was found, then wait and increase the counter
 *   of the wait times
     IF ( lv_is_chain_active = 'X' ).
       WAIT UP TO p_sec SECONDS.
       lv_times_counter = lv_times_counter + 1.
       WRITE: / 'Wait iteration no. ', lv_times_counter, ' for ', p_sec, ' seconds.'.
 *     Check the wait times number not exceeded, if it does raise
 *     error and exit the program
       IF ( lv_times_counter = p_times ).
         MESSAGE e026(rspc).
         EXIT.
       ENDIF.
 **   Dates entered are invalid (to date entered, but from date not)
 *    ELSEIF ( lv_is_error = 'X' ).
 *      MESSAGE e026(rspc).
 *      EXIT.
 *   If no active chain was found, the program is finished
     ELSE.
       EXIT.
     ENDIF.
ENDDO.

 

Activate the program.

 

Give descriptions to the programs selection parameters (in the program code editor, chose from the menu above Go To > Text Elements > Selection Texts and enter the descriptions as follows:

ParameterTextMore in Details
P_SECSeconds to Wait

Number of seconds to wait for the checked process chain to finish in case it is running

P_TIMESNo. of Times to WaitNumber of times to check if the process chain finished
SO_CHAINProcess Chain (Technical Name)

The technical name of the process chain to be checked if running (='A' - active status)

In case you would like to check more than one process chain, you may assign multiple chains in this parameter. The program will finish successfully only when all the process chains are not active.

 

Activate the Selection Texts.

 

Step #3

Create a variant to the wait program with the wanted parameters to be used on a program execution.

 

On transaction SE38 assign "ZBW_WAIT_FOR_CHAIN_TO_FINISH" as the program name, pick the "Variants" radio button and click on "Change" button.

Assign a variant name and click on "Create". Assign the wanted parameters, click on "Attributes" in the application bar, assign description to the variant and hit the "Save" button.

 

Step #4

Add the program to the wanted process chain using the process type "ABAP Program" with the suitable program variant created on Step #3.

 

* Remember that you should add this step of the wait program before a problematic step in a process chain which might bring to a lock / failure due to collisions between process chains loadings. So, in one process chain, the program will check if another (not itself !!!)process chain is active or not.

 

Good Luck!