SAP ABAP SPTA Parallel Processing

Bestimmt ist schon mal jeder an den Punkt gekommen, an dem er gemerkt hat, dass die sequentielle Ausführung seines ABAP Programms im SAP System einfach zu lange dauert. Dann merkt man, dass man sich mit dem Thema Parallel Verarbeitung im SAP beschäftigen muss. Dummerweise ist das Thema nicht so einfach wie in anderen Programmiersprachen wie z.B. C# oder Java umgesetzt. Wäre es nicht herrlich, wenn man einfach in ABAP nur die entsprechenden Zeilen C# Sourcecode schreiben könnte und schon geht es los?

    var task = Task.Factory.StartNew(new Action(Method));

Naja, so ist das halt im SAP. Wenn es einfach wäre, könnte es ja jeder. Um ABAP Programme parallel zu verarbeiten, existieren im SAP mehrere Möglichkeiten und ich möchte hier das SPTA Framework beschreiben. Ich halte das SPTA Framework für einen recht simplen Lösungsansatz, wenn man sich mit dem Thema Parallel Verarbeitung im SAP bereits auskennt, denn dem geneigten ABAP Entwickler wird hier recht viel Arbeit abgenommen. Trotzdem sollte man sich mit den Grundgedanken der parallelen Verarbeitung im SAP auch noch anderweitig vertraut machen.

Das SPTA ABAP Beispiel

Das gezeigte ABAP Beispiel geht nur auf den simpelsten Fall ein. Es wird ein großer Arbeitsvorrat an Daten in eine globale interne Tabelle geladen. Diese Tabelle wird dann in kleine Pakete aufgeteilt, die dann von einem Prozess verarbeitet werden und das Ergebnis wird dann zurück gegeben. Um es einfach zu halten, wird nicht auf Fehlerbehandlung oder das Wiederanstarten von fehlerhaften Prozessen eingegangen.



TYPES: mtt_data TYPE STANDARD TABLE OF  ...... WITH DEFAULT KEY,
       mtt_result type STANDARD TABLE OF ........ WITH DEFAULT KEY .

data: gt_data type mtt_data ,
      gt_result type mtt_result .

Parameters:
    rfcgroup TYPE spta_rfcgr OBLIGATORY MEMORY ID spta_rfcgr,
    maxtasks LIKE sy-index DEFAULT '10'.

START-OF-SELECTION .    

* hier wird der komplette Arbeitsvorrat angelegt, z.B. 1000 Abrechnungen, 
* die verarbeitet werden müssen
  gt_data = ....  

* Der Aufruf dies Funktionsbausteins beginnt die Verarbeitung. 
* Dabei müssen die drei angegeben ABAP FORMS 
* als Callback Routinen angegeben werden
 CALL FUNCTION 'SPTA_PARA_PROCESS_START_2'
    EXPORTING
      server_group             = rfcgroup
      max_no_of_tasks          = maxtasks
      before_rfc_callback_form = 'BEFORE_RFC'
      in_rfc_callback_form     = 'IN_RFC'
      after_rfc_callback_form  = 'AFTER_RFC'
      callback_prog            = sy-repid
    EXCEPTIONS
      invalid_server_group     = 1
      no_resources_available   = 2
      OTHERS                   = 3.

 END-OF-SELECTION.

 * Dieser Teil wird erst aufgerufen, wenn alle Prozesse fertig sind

  SKIP.

* hier kann jetzt das Ergebnis ausgegeben werden
  LOOP AT gt_result ASSIGNING FIELD-SYMBOL().

  ENDLOOP.

  SKIP.     

    
 

Die ABAP FORM BEFORE_RFC wird für jeden parallelen Prozess aufgerufen, der angestartet werden soll. In dieser ABAP FORM kann auf die globalen Variablen des Hauptprogramms zugegriffen werden. Für jeden Prozess wird ein Paket von der Größe 5 aufgebaut und dann an die Weiterverarbeitung weitergegeben. Dabei wird der globale Arbeitsvorrat jedesmal verkleinert.

  
    FORM before_rfc
  USING
      p_before_rfc_imp     TYPE spta_t_before_rfc_imp
   CHANGING
      p_before_rfc_exp     TYPE spta_t_before_rfc_exp
      pt_rfcdata           TYPE spta_t_indxtab
      p_failed_objects     TYPE spta_t_failed_objects
      p_objects_in_process TYPE spta_t_objects_in_process
      p_user_param.
 
  CONSTANTS: lc_pack_size type i value 5 .		

  DATA: ls_data LIKE LINE OF gt_data,
        lt_work     TYPE mtt_data.

  DO lc_pack_size TIMES.
    READ TABLE gt_data INDEX 1 INTO ls_data.
    IF sy-subrc IS INITIAL .
      APPEND ls_data TO lt_data .
      DELETE gt_data INDEX 1 .
    ENDIF .
  ENDDO .

* keine Daten mehr da, die weiterverarbeitet werden müssen
  IF lt_work IS INITIAL.
    CLEAR p_before_rfc_exp-start_rfc.
    EXIT.
  ENDIF.

* Wichtig, der Arbeitsvorrat für den parallelen Pozess
* muss hier in ein RFC Format verpackt werden.
  CALL FUNCTION 'SPTA_INDX_PACKAGE_ENCODE'
    EXPORTING
      data    = lt_work
    IMPORTING
      indxtab = pt_rfcdata.

* Es darf ein neuer RFC Prozess gestartet werden
  p_before_rfc_exp-start_rfc = 'X'.

ENDFORM .

  

In der ABAP FORM IN_RFC findet die eigentlich Verarbeitung der erstellten Arbeitspakete statt. Dieser Teil wird in einem eigenen SAP Dialog Prozess gestartet und kann daher auch nicht auf Variablen aus dem Hauptprogramm zugreifen.

    
      FORM in_rfc
  USING
      p_in_rfc_imp  TYPE spta_t_in_rfc_imp
   CHANGING
      p_in_rfc_exp  TYPE spta_t_in_rfc_exp
      p_rfcdata     TYPE spta_t_indxtab.

  DATA: lt_work     TYPE mtt_data ,
		lt_result   type mtt_result .

* Der Arbeitsvorrat muss entpackt werden
  CALL FUNCTION 'SPTA_INDX_PACKAGE_DECODE'
    EXPORTING
      indxtab = p_rfcdata
    IMPORTING
      data    = lt_work.

* hier passiert dann die Magie. 
    loop at lt_work ASSIGNING FIELD-SYMBOL() .
   
* hier kann dann auch das Resultat
* zusammengebaut werden
    ENDLOOP .

* Das Result muss verpackt werden
  CALL FUNCTION 'SPTA_INDX_PACKAGE_ENCODE'
    EXPORTING
      data    = lt_result
    IMPORTING
      indxtab = p_rfcdata.

  COMMIT WORK.


ENDFORM .

    

  

Nach dem die Verarbeitung eines Paketes in der Form IN_RFC beendet wurde, wird die ABAP Form AFTER_RFC aufgerufen.

    
      FORM after_rfc
   USING
      p_rfcdata            TYPE spta_t_indxtab
      p_rfcsubrc           TYPE sy-subrc
      p_rfcmsg             TYPE spta_t_rfcmsg
      p_objects_in_process TYPE spta_t_objects_in_process
      p_after_rfc_imp      TYPE spta_t_after_rfc_imp
   CHANGING
      p_after_rfc_exp      TYPE spta_t_after_rfc_exp
      p_user_param.

  DATA: lt_result     TYPE mtt_result.

* Das Ergebnis muss entpackt werden
  CALL FUNCTION 'SPTA_INDX_PACKAGE_DECODE'
    EXPORTING
      indxtab = p_rfcdata
    IMPORTING
      data    = lt_result.
 
  APPEND LINES OF lt_result
         TO gt_result.
  EXIT.

ENDFORM .

    
  

Links

Ein brauchbares englischsprachiges Tutorial