Entwicklung für Anforderungen einer asynchronen Operation

Sie können eine Anwendung CICS® entwickeln, die die asynchronen API-Befehle verwendet, um eine oder mehrere untergeordnete Aufgaben zu starten und Antworten von ihnen abzurufen. Wenn Sie Anwendungen zur Verwendung mit der asynchronen API entwickeln, müssen Sie den Ablauf der asynchronen API-Befehle und die verfügbaren Optionen für jeden Befehl berücksichtigen. Die Handhabung von Kanälen muss ebenfalls berücksichtigt werden, wenn Sie im Rahmen einer asynchronen Anforderung Eingaben übergeben oder Antworten empfangen wollen.

Mit den Optionen TIMEOUT und NOSUSPEND der Befehle FETCH CHILD und FETCH ANY haben Sie mehr Kontrolle über das Eltern-Kind-Verhalten, wodurch es noch einfacher wird, die Anforderungen an die Antwortzeit bei asynchronen Anwendungen zu erfüllen.

Überlegungen zur Programmierung und Empfehlungen

Im Folgenden finden Sie einige praktische Hinweise und empfohlene Vorgehensweisen für die Verwendung der asynchronen API CICS. Ihre Umgebungen und Anwendungen können jedoch unterschiedlich sein und von verschiedenen Ansätzen profitieren. Einzelheiten finden Sie in der Veröffentlichung IBM® Redbooks® IBM CICS Asynchronous API: Gleichzeitige Verarbeitung leicht gemacht.

Untergeordnete Aufgaben sollten GETs von Daten durchführen und UPDATEs der übergeordneten Aufgabe überlassen.
Eltern- und Kindaufgaben sind getrennte Arbeitseinheiten (UOW). Wenn z. B. eine übergeordnete Aufgabe abbricht, kann sie ihre eigene Arbeit zurückziehen, wird aber von der Ausführung der untergeordneten Aufgaben abgekoppelt. Wenn sich die untergeordneten Aufgaben auf GET-Aktionen beschränken, können sie sicher verworfen werden, ohne den Zustand der Daten zu gefährden. Es ist möglich, dass untergeordnete Aufgaben UPDATEs an Daten durchführen. Es kann jedoch erforderlich sein, eine Kompensationslogik zu kodieren, um Änderungen rückgängig zu machen, falls dies erforderlich ist.
Erlauben Sie demselben übergeordneten Programm, untergeordnete Aufgaben auszuführen und abzuholen.
Aus Gründen der Verwaltbarkeit sollte das übergeordnete Programm, das eine untergeordnete Aufgabe startet, das Programm bleiben, das die Ergebnisse der untergeordneten Aufgabe abruft. Dieser Vorgang ist besonders nützlich, wenn Sie den Befehl FETCH ANY verwenden, da es schwierig sein kann, die Befehle RUN TRANSID und FETCH ANY aufeinander abzustimmen, wenn sie sich in verschiedenen Programmen befinden. Beachten Sie auch, dass abgefragte Kanäle auf eine Link-Ebene skaliert sind. Die Weitergabe von Ergebnissen kann also problematisch sein, wenn nicht der Elternteil die Ergebnisse des Kindes abruft.
Tipp: Wenn Sie Antwortdaten von einer untergeordneten Aufgabe abrufen möchten, geben Sie CHANNEL in EXEC CICS RUN TRANSID an, auch wenn Sie keine Eingabedaten für die untergeordnete Aufgabe haben.
Eltern mit langen Laufzeiten sollten den Befehl FREE CHILD verwenden.
In einer lang laufenden übergeordneten Anwendung kann es zu einem Anstieg der Kontrollblöcke kommen, wenn untergeordnete Aufgaben abgeschlossen werden. Darüber hinaus kann es zu einer Ansammlung umfangreicher Kanaldaten kommen. Ohne Beendigung der Aufgabe kann das System CICS diese Daten nicht sicher verwerfen. Es ist ratsam, dass ein lang laufender übergeordneter Task alle abgerufenen Kanäle löscht und FREE CHILD Befehle an untergeordnete Tasks ausgibt, die nicht mehr benötigt werden.
Verfolgen Sie die abgerufenen Kanäle.
Die Datenübermittlung zwischen übergeordneten und untergeordneten Aufgaben erfolgt über CICS channel und Container. Um Daten von einer untergeordneten Aufgabe zurückzugeben, aktualisiert die untergeordnete Aufgabe Container auf ihrem aktuellen Kanal. Während der Beendigung von untergeordneten Aufgaben wird der Kanal von der AS-Domäne CICS verwaltet oder gehört ihr. Die übergeordnete Aufgabe kann den Kanal der untergeordneten Aufgabe abrufen, indem sie den Parameter CHANNEL in den Befehlen FETCH CHILD oder FETCH ANY angibt. Dieser Ansatz ist aktiver als eine einfache Anfrage. Der Kanal wird an den ausstellenden Elternteil gebunden.
Überprüfen Sie MAXTASK und legen Sie Transaktionsklassen fest.
Die Einfachheit der asynchronen API könnte zu mehr Transaktionen in einem CICS System führen. Es wird empfohlen, die Parametereinstellung MAXTASK zu überprüfen. Es ist ratsam, Kontrollen einzurichten, um die Menge der Arbeit zu begrenzen, die eine Region annimmt und die dazu führt, dass Aufgaben asynchron ausgeführt werden.
Parametrieren Sie Zeitüberschreitungen.
In vielen Fällen werden die Ergebnisse eines Childs benötigt, damit der Parent seine Geschäftslogik fortsetzen kann. Wenn Sie eine Zeitüberschreitung benötigen, oder wenn die Möglichkeit besteht, dass Sie dies in Zukunft benötigen, können Sie einen TIMEOUT-Parameter für den Befehl FETCH angeben. Der Wert der Zeitüberschreitung sollte parametrisiert werden, z. B. durch das Lesen aus einer Datei oder einer Datenbanktabelle zu einem früheren Zeitpunkt in der Anwendung. Indem Sie den TIMEOUT-Parameter einfügen und den TIMEOUT-Wert parametrisieren, verhindern Sie, dass der Code in Zukunft aktualisiert oder neu kompiliert werden muss.
Sie können die Befehle TIMEOUT und NOSUSPEND für Ihre FETCH CHILD und FETCH ANY verwenden, um die Vielseitigkeit der Anwendung zu verbessern und die geschäftlichen Anforderungen in einer Vielzahl von Situationen zu erfüllen:
  • Für alle untergeordneten Aufgaben, auf die Sie unbedingt eine Antwort benötigen, verwenden Sie FETCH ohne TIMEOUT oder NOSUSPEND.
  • Für untergeordnete Aufgaben, bei denen Sie eine zeitnahe Antwort benötigen, geben Sie in Ihrem Befehl FETCH einen TIMEOUT-Wert an.
  • Für untergeordnete Aufgaben, bei denen keine Antwort zulässig ist, geben Sie NOSUSPEND auf Ihrem FETCH Befehl an.

Beispiele

Beispiel: Ein Kreditkartenantrag

In diesem Beispiel wird eine Kreditkartenanwendung verwendet, um zu zeigen, wie die Befehle verwendet werden können.

Starten Sie die Bonitätsprüfung Kind Aufgaben
  1. Geben Sie die Kundendaten in einen neuen Kanal ein:.
    EXEC CICS PUT CONTAINER('CUSTDETAILS') CHANNEL(customerDetails)
  2. Rufen Sie den ersten Kreditprüfungsdienst mit einem Kanal an:
    EXEC CICS RUN TRANSID('CRD1') CHILD(creditCheck1_tkn) CHANNEL(customerDetails)
  3. Rufen Sie den zweiten Kreditprüfungsdienst über denselben Kanal an:
    EXEC CICS RUN TRANSID('CRD2') CHILD(creditCheck2_tkn) CHANNEL(customerDetails)

Ein übergeordnetes Programm kann nach der Ausgabe eines EXEC CICS RUN TRANSID -Befehls mit anderen Verarbeitungen fortfahren und kann danach jederzeit einen EXEC CICS FETCH -Befehl ausgeben, um die Ergebnisse einer untergeordneten Aufgabe abzurufen.

Abrufen einer Antwort von einer bestimmten untergeordneten Aufgabe
  1. Holen Sie die Antwort vom ersten Kind ab:
    
    EXEC CICS FETCH CHILD(creditCheck1_tkn) CHANNEL(credReply1_chan) 
              COMPSTATUS(credReply1_status)

    In diesem Fall wird die übergeordnete Verarbeitung blockiert, bis die untergeordnete Aufgabe ein Ergebnis liefert. Mit den optionalen Parametern NOSUSPEND und TIMEOUT kann die Blockierung je nach Wunsch verhindert oder eingeschränkt werden.

  2. Überprüfen Sie den Antwortcode des Befehls EXEC CICS FETCH CHILD , um sicherzustellen, dass der Befehl normal ausgeführt wurde.
  3. Wenn der Befehl EXEC CICS FETCH CHILD normal ausgeführt wurde, überprüfen Sie die COMPSTATUS des Childs, um sicherzustellen, dass er erfolgreich abgeschlossen wurde.
    • Wenn COMPSTATUS anzeigt, dass die untergeordnete Aufgabe erfolgreich abgeschlossen wurde, wird die Antwort vom Antwortkanal abgerufen.
      EXEC CICS GET CONTAINER('RESULT') CHANNEL(credReply1_chan)
    • Wenn COMPSTATUS anzeigt, dass die untergeordnete Aufgabe abgebrochen wurde, sollte die Logik der übergeordneten Anwendung entscheiden, was zu tun ist. CICS bereinigt alle Ressourcen, wenn die übergeordnete Transaktion abgeschlossen ist.
  4. Wiederholen Sie die Schritte 1 bis 3 für die zweite Kinderaufgabe.
Eine Antwort von einer abgeschlossenen untergeordneten Aufgabe erhalten

Es ist auch möglich, eine Antwort von einer abgeschlossenen untergeordneten Aufgabe mit dem Befehl EXEC CICS FETCH ANY abzurufen, der das Ergebnis derjenigen untergeordneten Aufgabe zurückgibt, die zuerst abgeschlossen wurde:


EXEC CICS FETCH ANY(creditCheck_tkn) CHANNEL(credReply_chan) 
          COMPSTATUS(credReply_status)

Überprüfen Sie wie gewohnt den Abschluss des Befehls FETCH ANY und die Seite COMPSTATUS des Kindes.

Befreie ein Kind

Als Teil der übergeordneten Aufgabe können Sie untergeordnete Aufgaben freigeben, wodurch die zugehörigen Ressourcen aufgeräumt werden und die Nutzung des Systemspeichers auf ein Minimum reduziert wird, was besonders für lang laufende übergeordnete Aufgaben nützlich ist. Wenn Sie beispielsweise drei untergeordnete Aufgaben gestartet haben, aber nur die Ergebnisse von einer benötigen, können Sie die verbleibenden zwei untergeordneten Aufgaben mit FREE CHILD bereinigen.


EXEC CICS FREE CHILD(creditCheck1_tkn)
EXEC CICS FREE CHILD(creditCheck2_tkn)
Tabelle 1. Referenz: Optionale Parameter
Befehl Optionaler Parameter Verwendung
EXEC CICS RUN TRANSID CHANNEL Benutzen Sie es zum:
  • Übergabe von Daten an ein Kind.
  • Empfangen von Daten von einem Kind.
  • Beide übermitteln und empfangen Daten von und zu einem Kind.
RESP Verwenden Sie es, um zu sehen, ob ein Befehl erfolgreich ausgeführt wurde
EXEC CICS FETCH Befehle CHANNEL Verwenden Sie diese Option, um Daten von einer untergeordneten Aufgabe zu empfangen, sofern beim ersten Befehl RUN TRANSID ein Kanal angegeben wurde.
NOSUSPEND Verwenden Sie diese Option, um die Blockierung eines FETCH -Befehls zu verhindern: Der Befehl kehrt sofort zurück, unabhängig davon, ob eine untergeordnete Aufgabe abgeschlossen wurde.

Wenn die untergeordnete Aufgabe beendet ist, wenn der Befehl ausgegeben wird, kehrt der Befehl sofort mit einer NORMAL-Antwort zurück. Wenn das Kind nicht fertig geworden ist, tritt die NOTFINISHED-Bedingung mit dem Wert RESP2 von 52 auf.

Zeitlimit Verwenden Sie diese Option, um einen FETCH -Befehl für eine bestimmte Zeitspanne warten zu lassen, bevor er zurückkehrt.

Sie können die maximale Zeit in Millisekunden angeben, die die übergeordnete Aufgabe auf die Beendigung einer untergeordneten Aufgabe warten soll. Wenn TIMEOUT mit einem Wert ungleich Null angegeben wird, unterliegt die übergeordnete Aufgabe nicht DTIMOUT.

Wenn die untergeordnete Aufgabe beendet wird, bevor TIMEOUT erreicht ist, kehrt der Befehl sofort zurück. Wenn die untergeordnete Aufgabe nicht beendet ist, bevor TIMEOUT erreicht ist, tritt eine NOTFINISHED-Bedingung mit einem RESP2 -Wert von 53 auf.

ABCODE Wenn COMPSTATUS anzeigt, dass ein Kind abgebrochen wurde, enthält ABCODE den Abbruchcode des Kindes.

Beispiel: Übergabe des Child-Tokens an ein verknüpftes Programm zum Abrufen der Antwort von der Child-Task

Die folgenden Schritte sind ein Beispiel dafür, wie Ein- und Ausgaben zwischen übergeordneten und untergeordneten Aufgaben mithilfe von Kanälen weitergegeben werden.

  1. Der übergeordnete Task PROGP1 übergibt Eingaben an einen untergeordneten Task in einem Kanal und verknüpft ihn dann mit einem lokalen Programm PROGP2.
    
    EXEC CICS PUT CONTAINER('REQ') FROM(REQUEST) CHANNEL('ASYNC-CHANNEL')
    EXEC CICS RUN TRANSID('CHLD') CHANNEL('ASYNC-CHANNEL') CHILD(CHILD-TOKEN)
    EXEC CICS PUT CONTAINER('CHILDTOKEN')  FROM(CHILD-TOKEN) CHANNEL('ASYNC-CHANNEL')
    EXEC CICS LINK PROGRAM('PROGP2') CHANNEL('ASYNC-CHANNEL')

    Eine Kopie der vom Elternteil erstellten ASYNC-CHANNEL wird an das Kind weitergegeben, und die Kopie wird zum aktuellen Kanal für das Anfangsprogramm des Kindes. Der Name des Kanals wird vom Kopiervorgang beibehalten. Wenn also das untergeordnete Programm PROGC1 EXEC CICS ASSIGN CHANNEL ausgeben würde, würde ASYNC-CHANNEL zurückgegeben.

  2. Die untergeordnete Aufgabe mit der Transaktions-ID CHLD und dem Programm PROGC1 erhält die Eingabe von ihrem aktuellen Kanal:
    EXEC CICS GET CONTAINER('REQ')

    Die untergeordnete Aufgabe fährt dann mit ihrer Logik fort, erzeugt eine Antwort für die übergeordnete Aufgabe und legt sie in einem Container innerhalb ihres aktuellen Kanals ab:

    
    EXEC CICS PUT CONTAINER('RESP') FROM(RESPONSE)
    EXEC CICS RETURN
  3. Die übergeordnete Aufgabe PROGP2 holt die untergeordnete Antwort ab und fährt mit einiger Geschäftslogik fort, bevor sie zu PROGP1 zurückkehrt:
    
    EXEC CICS GET CONTAINER ('CHILDTOKEN') INTO(CHILD-TOKEN)
    EXEC CICS FETCH CHILD(CHILD-TOKEN) CHANNEL (FETCHED-CHANNEL)
    EXEC CICS GET CONTAINER('RESP') CHANNEL(FETCHED-CHANNEL)

    Wenn die übergeordnete Task den Antwortkanal von der untergeordneten Task abruft, erzeugt CICS einen eindeutigen Kanalnamen und bindet den Kanal an die aktuelle Programmverknüpfungsebene. In diesem Beispiel gehört der abgerufene Kanal PROGP2. Wenn PROGP2 zu PROGP1 zurückkehrt, wird der abgeholte Kanal von CICS gelöscht. Der Antwortkanal eines Childs kann nur einmal von der Parent-Task abgerufen werden.

Beispiel: CICS Asynchrone API-Abrufvariante

Bevor Sie beginnen: Der vollständige Quellcode dieses Beispiels ist verfügbar unter GitHub wo Sie auch Anweisungen zur Einrichtung und Ausführung finden.

Dieses COBOL Beispiel hat ein übergeordnetes Programm ASYNCPG1, um die Verwendung der EXEC CICS FETCH Befehle mit und ohne Option TIMEOUT oder NOSUSPEND zu demonstrieren. Die Anwendung hat auch vier untergeordnete Programme: ASYNCCH1, ASYNCCH2, ASYNCCH3, ASYNCCH4.

ASYNCPG1 startet vier asynchrone untergeordnete Aufgaben. Dann werden 3 verschiedene Arten von Abrufen durchgeführt, um die Antwort zu erhalten, je nach Geschäftsanforderung, wie folgt:
  • Das übergeordnete Programm benötigt die Antwort des ersten untergeordneten Programms, also verwenden Sie FETCH CHILD ohne die Option SUSPEND oder TIMEOUT.
    
    EXEC CICS FETCH CHILD(CHLDTOKN1) CHANNEL(CHLDCHNL1)
               COMPSTATUS(CVDA)
               RESP(W-RESP) RESP2(W-RESP2)
               END-EXEC.
  • Das übergeordnete Programm kann bis zu 1000 Millisekunden warten, wenn es die Antwort des zweiten untergeordneten Programms abruft, verwenden Sie also FETCH CHILD TIMEOUT.
    
    EXEC CICS FETCH CHILD(CHLDTOKN2) CHANNEL(CHLDCHNL2)
               TIMEOUT(TIMEOUT1)
               COMPSTATUS(CVDA)
               RESP(W-RESP) RESP2(W-RESP2)
               END-EXEC.
    wobei TIMEOUT1 wie unten gezeigt definiert ist und dynamisch im Programm oder durch Lesen aus einer Datei oder Datenbank geändert werden kann, um Ihrer Umgebung zu entsprechen:
    01 TIMEOUT1     PIC S9(8) USAGE BINARY VALUE 1000.
  • Für das dritte und vierte Kind kann das übergeordnete Programm ein beliebiges Ergebnis haben, kann es sich aber nicht leisten, zu warten, und verwendet daher FETCH CHILD NOSUSPEND.
    
    EXEC CICS FETCH ANY(ANYTOKN) CHANNEL(ANYCHNL)
               NOSUSPEND COMPSTATUS(CVDA)
               RESP(W-RESP) RESP2(W-RESP2)
               END-EXEC.