One of the customers reported they got “Error Generating Program” (Error message /SAPAPO/TSM141) during their background job of /SAPAPO/TSCUBE (with parallel processing profile). The error does not always happen, and re-running the job also successful.
This is a kind of not-so-easy-to-investigate issue because it is not reproducible, only happens with large dataset and parallel processing.
I did some search based on below steps.
1) What is generated program in APO system?
In APO system, there’re lots of program (can be displayed in SE38) with strange GUIDs are so-called generated program. They’re generated based on certain system setting (like, MPOS, Planning Area, Macro, Infocube, …) and generated from a template program. (Refer to note 335528 for more information.)
These generated program are those really to be executed during run time.
2) What kind of errors can happen during generation of these programs?
The programs are generated in function module /SAPAPO/TS_GENER_CODING. Go inside this FM, the below coding is used to (re-)generate these programs.
CALL FUNCTION ‘RSS_PROGRAM_GENERATE’
i_uni_idc25 = lv_repuid
i_program_class = i_progclass
i_program_title = lv_prog_title
i_debug_level = lv_debug_level
* I_NO_SYNTAX_CHECK = true
I_NO_PRETTY_PRINTER = true
* I_NO_RDIR_CHECK = true
I_USE_METACLASS = true
i_force_generation = lv_force_generation
e_program_name = e_gen_repid
e_error_line = lv_err_line
e_error_message = lv_err_msg
invalid_program_class = 1
invalid_unique_id = 2
template_not_found = 3
template_syntax_error = 4
program_syntax_error = 5
foreign_lock = 6
system_failure = 7
internal_error = 8
OTHERS = 9.
Here we can see there’re 9 kinds of errors. According to my experience, mostly happened errors are error 5 and error 6. Normally error 5 is reproducible while error 6 is likely to happen when parallel process exists. (Errors 1-4 should be always reproducible, while errors 7-9, still no idea for them.)
So in this case, I guess the error should be error 6 since the issue happens randomly.
3) Why error 6 happens?
If more than one process try to generate the same program, foreign lock error will happen.
In the above FM RSS_PROGRAM_GENERATE, we can see program_enqueue is called to block the program to be generated.
During processes with parallel processing profile, for each block, FM /SAPAPO/TS_GENER_CODING will be called. If the processes are highly paralleled, foreign lock error is very likely to happen. For example, in TSCUBE, all source data is from the same cube, and all CVCs are based on the same MPOS, so it will always try to check the generated program for the same MPOS/CUBE when processing each block.
4) When are the programs re-generated and are they always re-generated during processing like TSCUBE?
FM /SAPAPO/TS_GENER_CODING is called very often during DP/SNP processes, but FM RSS_PROGRAM_GENERATE is actually not always necessary.
In FM /SAPAPO/TS_GENER_CODING, it first check whether the program is generated from global (buffer) table ‘gt_gen_buffer’. If yes, exit directly. However during parallel processing, this buffer table will always be blank in each parallel process.
Then there’s another check in “PERFORM report_name_build”. In this routine, it will check the timestamp of the generated programs and the last generation/activation time of the corresponding object. If regeneration is necessary, ‘lv_necessary’ will be returned as ‘X’.
5) When ‘lv_necessary’ is returned as ‘X’ in process of TSCUBE.
By debugging a small example in internal system, I found in the process, it is checking the below three things:
(1) Compare the last generation time of the Infocube (from BW) with the last generation time of infocube form routines.
– Last generation time of infocube can be get from function module ‘/SAPAPO/DPBW_PROVIDER_GET’. In SE37, execute this FM, input infocube name and execute, the timestamp can be get from E_S_DTA-TIMESTMP.
– Last generation time of infocube form routines can be get from table field /SAPAPO/TSPLOGEN-LAST_GEN, selection condition is infocube name with MPOS blank, PROGCLASS=PSTRU_ICUBE_FORMS.
*If the last generation time of the Infocube is later than the last generation time of infocube form routines, ‘lv_necessary’ is set to ‘X’.
(2) Compare the last generation time of the MPOS with the last generation time of basic form routines for the MPOS.
– Last generation time of the MPOS can be found in table /SAPAPO/TSPLOBTE-LAST_GEN.
– Last generation time of MPOS basis form routines can be get from table field /SAPAPO/TSPLOGEN-LAST_GEN, selection condition is MPOS name with infocube blank, PROGCLASS=PSTRU_BASIC_FORMS.
*If the last generation time of the MPOS is later than the last generation time of basic form routines, ‘lv_necessary’ is set to ‘X’.
(3) Compare generation time of infocube and MPOS with the last generation of master data.
– First get the last generation time of the infocube and the MPOS as in (1) and (2).
– Then the last generation time of master data can be get from table field /SAPAPO/TSPLOGEN-LAST_GEN, selection condition is MPOS name together with infocube name, PROGCLASS=PSTRU_MD_GENERATE.
*If the last generation time of the Infocube is later than the last generation time of master data, ‘lv_necessary’ is set to ‘X’.
*If the last generation time of the MPOS is later than the last generation time of master data, ‘lv_necessary’ is set to ‘X’.
6) Why in customer system, the programs are necessary to be generated.
Based on the findings in 5), it is easy to get which program is to be generated if TSCUBE is executed again in customer system.
To avoid program generation during batch run, it is a good idea to have them generated before hand. This can be done using report /SAPAPO/TS_PSTRU_GEN. Just check which of (1) (2) (3) is/are necessary to be generated and generate them before starting the job.
7) Solution and general information.
To avoid program generation error during TSCUBE background job, after any change is made to MPOS/Infocube, it is a good idea to use report /SAPAPO/TS_PSTRU_GEN to generate (1) (2) (3).