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 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 .
Ein brauchbares englischsprachiges Tutorial