Thursday, June 27, 2013

SAP ECC6.0 : CSLEO_ENQUEUE and ME_PURCHASE_DOCUMENT_READ affecting output type.

When a program such as ME22N has already lock EKKO/EKPO tables thru ENQUEUE_EMEKKOE function, other programs won't be able to manipulate those standard tables until it is de-queue or released. Of course, it has to finish its one LUW (or known as Logical Unit of Work). But sometimes, programs we modified or wrote may somehow try to grab or should I say fight to use the same table. As a result we are embroiled in whether to let the initial LUW to finish or not. So we have UPDATE TASK at hand to let next program in waiting to finish after the initial LUW finish. Then, today, I learn something new, which is CSL. CSL is Cross System Lock and it works in a specified way to ensure that critical program that is running and updating a tables does not get used by other programs. CSL holds a major topic of its own. You can find it here

I met CSL in an issue which I had to troubleshoot why an output type, with external send '5', kept producing "Update Was Terminated" message. So, I began my journey to go through 3 programs : RSM13000, RSNAST00, and ZSAPFM06P_IDT2. RSM13000 relates to RV_UPDATE_MESSAGE function module. RSNAST00 is where you normally use it to test your output type. And the ZSAPFM06P_IDT2 is our main character which is also a driver or print program. Now, the issue at hand is we need to know why error "Update Was Terminated" message is pop up and the output type was not sent out. 

Naturally, the very first thing we will do, is to double check the output type profile and settings just to ensure that everything is okay. Then in my case, I personally love ST05 (Trace Analysis, yes you are right) to record everything what went wrong in the field. So I would activate my ST05 and then repeat the whole process until it gets the error. Then I would returned to ST05 and get a quick glance where the error is coming from then do a back tracing. Ever heard of back tracing? It's an idea which I developed over my 10 years of work with trouble shooting ABAP program. Sometimes, my back tracing works. Unfortunately, this time, it doesn't work at all. The reason is because the error was triggered from print program that was running in the background. So much information I can get from ST05. But ST05 is the primary forensic tool that I will use to trace my program. 

So here's my result when I used ST05 and pin-pointing suspects of crime or partner accessory to the crime scene:

1. ZSAPFM06P_IDT2->ZFM06PF02_IDT2->AUSGABE_POS
- ZFM06PF01_IDT2->POS_AUSGABEN
- ZFM06PF02_IDT2->ME_PURCHASE_DOCUMENT_DATA_READ

This is the first suspect, that I had to stop and examined him. Because when I used RSNAST00 to run him, it went to an error saying SE38 was not found in the process. SE38? Why would I use SE38? Simple. When one use RSNAST00 via SE38 to run, the SY-TCODE will be SE38. It was using SE38 as the main catalyst to determine which program was using to display or hold a PO document. So I thought I found my suspect but it was not because SY-TCODE would be holding another value if it's running in the background. 

2. ZFM06PF02_IDT2->AUSGABE_KOPF
This is the second suspect, which I thought is the culprit because the XDIALOG was not set to blank. General speaking, at least, I know that to run a print program in the background, it should not have any printer setting popping up or it may stall the whole background process leading to "Update Was Terminated". Of course, I used my surgical tool to make an incision and make sure XDIALOG is set to blank for the moment. Temporarily. Then I re-ran my test, the error message was still displaying despite I had it set to blank.

Although these 2 suspects were ready to be left alone but I had no intention to letting them go away. I was thinking I am missing something. So I had myself sit down and trace from the beginning especially when I clicked on the "Save" button. So it came across this 'ENQUEUE_EMEKKOE' in the trace analysis (ST05). Hence, I put a break-point at that very spot ie, 

SAPLMEXF->LMEXFU10->MQ_ENQUEUE_DOCUMENT

Then I ran from the beginning that is executing ME22N. The break-point was hit. Okay, it had to enqueue EKKO/EKPO, so the PO document can be used. Next, I went to repeat the output type again. Strange, it hit the "Update Was Terminated" again. So, what on earth, is happening. I went to see SM13 and look at this termination error. It said,
User XXXX already processing Purchase Order NNNNN
Okay, this meant something somewhere wants to use the EKKO/EKPO table but they cannot do so because ME22N has already enqueue these tables in the first place. So, the big question comes, 
Which program wants to access EKKO/EKPO?
Now, I had two questions, why does it need to access it again? And of course, the next question would which program wants to access them. So, the next two hours I had to start again at somewhere to try to find out which program. Was it the RSM13000? Or was it the RSNAST00? Or is it the print program itself, ZSAPFM06P_IDT2? I had to look into all these again. 

Firstly, RSM13000 is an RV_UPDATE_MESSAGE which I don't think it will do much since it is a bridge to call RSNASTED or RSNAST00 depending on which type of output type you are using. So that's leave print program alone ZSAPFM06P_IDT2. Just to prove it's innocence, I used its original clone SAPFM06P to run it. Voila, there was not a single error message at all. This is getting me somewhere! I opened two screens; each side by side so when I trace I would know what was the difference between these two print program. Well, behold, the logic was totally different from the other. One was querying KOMP using RV_PRICE_PRINT_READ and the other was using ME_PURCHASE_DOCUMENT_READ. The purpose of these two standard function calls is to derive the PO document's price/condition. RV_PRICE_PRINT_READ does not try to lock the EKKO/EKPO but ME_PURCHASE_DOCUMENT_READ tried to do a ENQUEUE_EMEKKOE again despite the ME22N had already done so. When ME_PURCHASE_DOCUMENT_READ tried to enqueue EKKO/EKPO, it went to check if there's another program is also using the table via CSLEO_ENQUEUE. Here's how I come to the conclusion that our culprit of this whole error was CSLEO_ENQUEUE or CSL (Cross System Lock). 

Cross System Lock had the system lock up so other program does not try to overtake the current program and used the table. Cross System Lock uses token concept to determine which program in a cross system is using a lock down table. Therefore, this has made my troubleshooting easier now.

Finally, I understood that this ZSAPFM06P_IDT2 which was written previously, uses ME_PURCHASE_DOCUMENT_READ to get KOMP (Pricing/Condition). And doing so, the call function tries to enqueue EKKO/EKPO and CSL had to walk in to tell us that we cannot do so because ME22N is already using it. That's why I get the error "Update Was Terminated" -> User "me" already processing Purchase Order "nnnnnnnnnn"

Though I have found out why the unduly "Update Was Terminated" error message occurs but there is still one more problem i.e. the customized program was original copy out and modified just for output type 1 - printing only. The NACHA (Output Type) 5 was not in the coding. No email will be send out. Hence, you need to find that spot that prepare all the email parameters and especially in OPEN_FORM function which it will export recipient and sender. In my case, it will be as below :


1. Routine AUSGABE_KOPF:
- When the coding starts to do task differently according to NACHA (Output type), you will need the following coding, 
      DATA lvs_comm_type   TYPE ad_comm,
             lvs_comm_values TYPE szadr_comm_values.

      CALL FUNCTION 'ADDR_GET_NEXT_COMM_TYPE'
        EXPORTING
          strategy           nast-tcode
          address_number     lfa1-adrnr
        IMPORTING
          comm_type          lvs_comm_type
          comm_values        lvs_comm_values
        EXCEPTIONS
          address_not_exist  1
          person_not_exist   2
          no_comm_type_found 3
          internal_error     4
          parameter_error    5
          OTHERS             6.

      IF sy-subrc <> 0.
        "Nothing to display.
      ENDIF.

      MOVE-CORRESPONDING nast TO intnast.
      MOVE sy-repid           TO xprogramm.

      CALL FUNCTION 'CONVERT_COMM_TYPE_DATA'
        EXPORTING
          pi_comm_type              lvs_comm_type
          pi_comm_values            lvs_comm_values
          pi_country                lfa1-land1
          pi_repid                  xprogramm
          pi_snast                  intnast
        IMPORTING
          pe_itcpo                  itcpo
          pe_device                 xdevice
          pe_mail_recipient         lvs_recipient
          pe_mail_sender            lvs_sender
        EXCEPTIONS
          comm_type_not_supported   1
          recipient_creation_failed 2
          sender_creation_failed    3
          OTHERS                    4.
      IF sy-subrc <> 0.
        "Avoid cancellation with message TD421
        retco '1'.

        PERFORM protocol_update USING '740' space space space space.

        "Dummy message to make the message appear in the where-used list
        IF 2.
          MESSAGE s740(me).
        ENDIF.

        EXIT.
      ENDIF.

      IF xdevice 'MAIL'.
        CALL FUNCTION 'SX_ADDRESS_TO_DEVTYPE'
          EXPORTING
            recipient_id lvs_recipient
            sender_id    lvs_sender
          EXCEPTIONS
            err_invalid  1
            err_system   2
            OTHERS       3.
        IF sy-subrc <> 0.
          retco '1'.

          PERFORM protocol_update USING '740' space space space space.

          IF 2.
            MESSAGE s740(me).
          ENDIF.

          EXIT.
        ENDIF.
      ENDIF.
Now, my issue is complete and user can issue email without trouble using the new output type. 

Here's some additional source to help you understand more when you click the "SAVE" button at output type page. (FCODE = 'V70S', this function code is standard code). Sometime we would like to know what are the function modules that were execute in UPDATE TASK mode.

1. CL_PO_HEADER_HANDLE_MM========CP -> CL_PO_HEADER_HANDLE_MM========CM00H -> PO_POST -> CALL FUNCTION 'MEPO_DOC_POST'
2. SAPLMEPO -> ISAUTO_SCH_EMM_MM06EF0B_BUCHENE -> BUCHEN -> CALL FUNCTION 'ME_UPDATE_DOCUMENT' IN UPDATE TASK -> LINE 51 (ENHANCEMENT 8)
3. SAPLMEPO -> FM06ECDC -> CD_CALL_EINKBELEG -> CALL FUNCTION 'EINKBELEG_WRITE_DOCUMENT' IN UPDATE TASK -> LINE 13
4. SAPLMEPO -> MM06EF0B_BUCHEN -> BUCHEN -> CALL FUNCTION 'ME_UPDATE_QUOTA_DIALOG' IN UPDATE TASK
5. SAPLEINU -> LEINUU05 -> ME_UPDATE_DOCUMENT -> CALL FUNCTION 'OUTBOUND_CALL_01000730_E'
6. SAPLVMSG -> LVMSGU02 -> RV_MESSAGE_UPDATE -> CALL FUNCTION 'WFMC_MESSAGE_SINGLE'


Edited on 06/28/2013 Friday 11:00 am. 

Reference  :

williamwilstroth... CSL, CSLEO_ENQUEUE, ERROR "Update Was Terminated"