PSB-Terminierung für CICS-Umgebungen

In einer CICS-Umgebung wird die Terminierung eines Programmspezifikationsblocks (PSB) anders bearbeitet als in Nicht-CICS-Umgebungen.

In den folgenden Abschnitten wird beschrieben, wie ein PSB terminiert wird, wie ein alternativer PSB zur Ausführungszeit verwendet wird und wie ein PSB mit einem aufgerufenen Programm gemeinsam genutzt wird.

PSB-Terminierung

Bevor ein CICS-DL/I-Programm auf die in einem Programmspezifikationsblock (PSB) definierte Datenbank zugreifen kann, muss das Programm den betreffenden PSB terminieren. Nach Abschluss des Datenbankzugriffs muss das Programm den PSB beenden. In Rational COBOL Runtime wird die PSB-Terminierung für ein Programm automatisch durchgeführt. Sie müssen jedoch wissen, wann ein PSB terminiert ist, weil die folgenden Funktionen von der PSB-Terminierung beeinflusst werden:
Sperrung von Segmentdatensätzen
Sperren für Segmentaktualisierungen werden bei Beendigung des PSB freigegeben.
Datenbankpositionierung
Die Datenbankposition geht bei Beendigung des PSB verloren.
Festschreibung von Aktualisierungen
Änderungen werden bei Beendigung des PSB festgeschrieben (in die Datenbank geschrieben).

Der PSB wird terminiert, wann immer ein DL/I-Aufruf für das Programm ausgegeben wird und der PSB zum betreffenden Zeitpunkt nicht bereits terminiert ist. Der in 'dliLib.psbData.psbName' benannte PSB ist der terminierte PSB.

Wenn Sie eine Anweisung 'call' oder 'transfer to program' verwenden, um die Programmsteuerung zu übertragen, muss das Zielprogramm nicht denselben PSB verwenden, den das übertragende Programm verwendet.

Der PSB endet, sobald eine CICS-Anweisung SYNCPOINT oder SYNCPOINT ROLLBACK ausgegeben wird. Synchronisationspunkte (SYNCPOINTs) treten auf, wenn eine der folgenden Bedingungen zutrifft:
  • Das Programm der höchsten Ebene in einer Ausführungseinheit wird erfolgreich beendet und gibt die Steuerung an CICS zurück. Bei CICS entspricht eine Ausführungseinheit einer einzelnen Transaktion und besteht aus allen EGL-Programmen und Nicht-EGL-Programmen, die mithilfe einer Anweisung 'transfer to program' oder 'call' die Steuerung untereinander übertragen. Bei Nicht-EGL-Programmen umfasst dies auch alle Übertragungen, die eine Anweisung CALL, einen CICS-Befehl LINK oder einen CICS-Befehl XCTL verwenden.
  • Ein Programm verwendet eine Anweisung 'converse' und einer der folgenden Parameter ist auf 1 gesetzt:
    • converseVar.segmentedMode (nimmt standardmäßig den Wert 1 an, wenn die Programmeigenschaft auf YES gesetzt ist)
    • converseVar.commitOnConverse
  • Es findet eine Übertragung mit einer Anweisung 'transfer to transaction' statt.
  • Ein Programm ruft die Funktion 'sysLib.commit' auf.
  • Wenn ein PSB momentan terminiert ist, übergibt ein EGL-Programm die Steuerung mithilfe einer Anweisung 'transfer to program', und eine der folgenden Bedingungen trifft zu:
    • Die Übertragung erfolgt auf ein Nicht-EGL-Programm (und ein Nicht-VisualAge Generator-Programm).
    • Die Erstellungsdeskriptoroption 'synchOnPgmTransfer' ist für das übertragende Programm auf YES gesetzt.
    • Die Erstellungsdeskriptoroption 'synchOnPgmTransfer' ist für das übertragende Programm auf NO gesetzt, und der im PSB-Datensatz des übertragenden Programms referenzierte Standard-PSB unterscheidet sich von dem Standard-PSB, der im PSB-Datensatz des Zielprogramms referenziert ist. Um die Unterschiede beim Verhalten zu minimieren, wenn ein übertragendes Programm sowohl für CICS als auch für IMS/VS generiert wird, setzen Sie die Erstellungsdeskriptoroption 'synchOnPgmTransfer' auf NO.
  • Ein von EGL aufgerufenes DL/I-Programm kehrt zum aufrufenden Nicht-EGL-Programm zurück, der PSB wurde nicht an die Struktur 'dliLib.psbData' übergeben, und es wurden keine Programmkommunikationsblöcke (PCBs) mithilfe von PCB-Datensätzen übergeben.
Eine Anweisung SYNCPOINT ROLLBACK erfolgt in folgenden Situationen:
  • Ein EGL-Programm ruft die Funktion 'sysLib.rollback' auf.
  • Ein Programm wird aufgrund einer Fehlerbedingung beendet.
Bei einem Rollback werden sämtliche Änderungen zurückgesetzt, die seit dem Start der logischen Arbeitseinheit (LUW) an Datenbanken und wiederherstellbaren Dateien vorgenommen wurden.

Alternative PSBs zur Ausführungszeit

Verwenden Sie beim Erstellen eines DL/I-Programms die Eigenschaft 'psb', um den Namen einer Programmvariablen anzugeben, die auf einem PSBRecord-Abschnitt basiert. EGL verwendet den PSBRecord-Abschnitt, der dieser Variablen zugeordnet ist, um DL/I-Aufrufe für die Segmente zu erstellen, die in dem PSB definiert sind, und um Änderungen zu überprüfen, die Sie an den DL/I-Aufrufen vornehmen. In einer CICS-Umgebung verwendet Rational COBOL Runtime den PSB-Namen auch für die PSB-Terminierung zum Zeitpunkt der Programmausführung.

Möglicherweise wollen Sie jedoch mit demselben Programm einen alternativen PSB verwenden. Der alternative PSB beschreibt Datenbanken, die dieselbe Struktur wie der PSB des Programms haben, während die Datenbanken selbst jedoch unterschiedlich sein können. So könnten Sie beispielsweise mit einer Gruppe von Testdatenbanken für die Programmentwicklung und mit einer entsprechenden Gruppe von Produktionsdatenbanken mit den echten Produktionsdaten arbeiten.

Wenn Sie einen alternativen PSB verwenden wollen, kann Ihr Programm den terminierten PSB dynamisch ändern, indem der Name des alternativen PSB in 'dliVar.dliPsbName' versetzt wird, bevor die erste DL/I-Funktion ausgeführt wird. Der alternative PSB muss mit dem PSB des Programms übereinstimmen, mit Ausnahme der Datenbanknamen.

Terminierten PSB mit einem aufgerufenen Programm gemeinsam nutzen

Ein aufgerufenes und ein aufrufendes Programm können nur dann beide ein DL/I-Programm sein, wenn sie denselben PSB gemeinsam nutzen oder wenn eine Commit-Operation den PSB beendet, bevor der Aufruf eines Programms bzw. die Rückkehr zu einem Programm erfolgt, das einen anderen PSB verwendet. Wenn Ihr Programm die Eigenschaft 'callInterface' auf CBLTDLI setzt, können Sie den PSB mit einem anderen Programm gemeinsam nutzen, indem Sie die Struktur 'dliLib.psbData' oder die PCB-Datensätze im Aufruf sowohl für das aufgerufene als auch für das aufrufende Programm übergeben. Wenn Ihr Programm die Eigenschaft 'callInterface' auf AIBTDLI (Standardwert) setzt, übergeben Sie die Struktur 'dliLib.psbData' oder die PCB-Datensätze, wenn es sich bei dem aufrufenden oder aufgerufenen Programm um ein Nicht-EGL-Programm handelt.

Wenn es sich sowohl bei dem aufgerufenen als auch dem aufrufenden Programm um ein EGL-Programm handelt und der PSB vor dem Aufruf terminiert war, wird der PSB im aufgerufenen Programm von EGL nicht erneut terminiert.

Sie können einen PSB zwischen EGL-Programmen und Nicht-EGL-Programmen gemeinsam nutzen. Wenn die Struktur 'dliLib.psbData' als Parameter übergeben wird, wird ein 12-Byte-Bereich übergeben. Die ersten 8 Byte enthalten den PSB-Namen; die verbleibenden 4 Byte enthalten die Adresse des CICS-Benutzerschnittstellenblocks (UIB). Ist der PSB nicht terminiert, ist die UIB-Adresse 0.

Wenn Sie einen PSB zwischen EGL-Programmen und Nicht-EGL-Programmen gemeinsam nutzen, sollte das aufgerufene Programm die UIB-Adresse vor der Terminierung überprüfen. Ist die UIB-Adresse nicht 0, sollte der PSB nicht erneut terminiert werden. Wenn das aufgerufene Programm den PSB beendet, muss das UIB-Adressfeld auf 0 gesetzt werden. Wenn der PSB erneut terminiert wird, sollte das UIB-Adressfeld auf die von CICS zurückgegebene UIB-Adresse gesetzt werden.

Wenn ein Programm einen terminierten PSB mit einem aufgerufenen EGL-Programm gemeinsam nutzen muss, sollte ein 12-Byte-Bereich an das Programm übergeben werden. Die ersten 8 Byte sollten den PSB-Namen enthalten, und die verbleibenden 4 Byte sollten die UIB-Adresse enthalten. Ist der PSB nicht terminiert, sollte die UIB-Adresse 0 sein. Bei Rückgabe spiegelt die UIB-Adresse den aktuellen Terminierungsstatus des PSB wider.

Wiederherstellung nach einem Deadlock in der Warteschlangensteuerung für Datensätze

Aktualisierte Datensätze werden erst dann in die Datenbank geschrieben, nachdem der PSB beendet wurde. Ihr Programm erhält bis zur Beendigung des PSB die exklusive Nutzung dieser Datensätze, da die EGL-E/A-Anweisung 'get...forUpdate' andere Programme davon abhält, einen Datensatz zu ändern, bis er in die Datenbank geschrieben wurde. Dies kann zur folgenden Deadlock-Situation führen:
  • Ihr Programm (Programm 1) sperrt Datensatz A.
  • Ein anderes Programm (Programm 2) sperrt Datensatz B.
  • Sie versuchen, Datensatz B zu ändern.
  • Programm 2 versucht, Datensatz A gleichzeitig zu ändern.

Wenn CICS eine Deadlock-Situation feststellt, wird eines der Programme abnormal beendet. Darüber hinaus werden die an der Datenbank vorgenommenen Änderungen zurückgesetzt, und es wird eine Fehlernachricht an das Terminal geschrieben, in der die Ursache für die Beendigung des Programms erläutert wird.

Wenn eine abnormale Beendigung eines Programms für die Benutzer des Programms inakzeptabel ist, können Sie Ihr Programm in den CICS-Tabellen als wiederanlauffähig definieren. Informationen zum Wiederanlauf von Programmen finden Sie unter 'EGL-Programme nach einem DL/I-Deadlock erneut starten' in diesem Thema.

Wenn das Programm wiederanlauffähig ist und CICS eine Deadlock-Situation feststellt, setzt CICS die Änderungen, die das Programm seit der Terminierung des PSB vorgenommen hat, zurück und startet das Programm am Anfang der Transaktion erneut.

Wenn Ihr Programm im Segmentmodus (pseudodialogfähigen CICS-Modus) ausgeführt wird, wird das jüngste Segment des Programms erneut gestartet, und Sie benötigen im Programm keinen speziellen Code für Neustart.

Wenn ein nicht segmentiertes Programm (interaktives CICS-Programm) erneut gestartet wird, beginnt das Programm die Verarbeitung erneut ganz oben. Sie können ermitteln, ob das Programm erneut gestartet wurde, indem Sie das Programm einen Test auf den Wert 1 im Feld 'dliVar.cicsRestart' ausführen lassen. Wenn 'dliVar.cicsRestart' den Wert 1 aufweist, können Sie eine Nachricht an den Programmbenutzer schreiben, in der Sie erklären, dass das Programm aufgrund eines Deadlocks erneut gestartet wurde, und anschließend die anfängliche Programmmaske erneut anzeigen.

Mit EGL generierte Programme nach einem DL/I-Deadlock erneut starten

Wenn Sie die DL/I-Funktion für Programmisolation verwenden, können Deadlocks zwischen zwei Transaktionen auftreten, die denselben Datensatz sperren. Die Programme versuchen gleichzeitig, denselben Datensatz zu aktualisieren. Wenn beide Aktualisierungen akzeptiert werden, geht eine der Änderungen verloren. Wenn CICS feststellt, dass Daten verloren gehen, wird die Transaktion mit dem Abbruchcode ADLD abnormal beendet.

Der Rational COBOL Runtime-Handler für abnormale Beendigung fordert einen Neustart für Programme an, die aufgrund eines Deadlocks abnormal beendet werden. In den folgenden Situationen startet CICS die Transaktion vom Beginn an erneut:
  • Sie haben DTB=YES und RESTART=YES in der Programmsteuertabelle für das Transaktionsprogramm angegeben.
  • Im CICS-Programm für Transaktionsneustart (DFHRTY) ist angegeben, dass die Transaktion erneut gestartet werden soll.
  • Die Warteschlangen für temporären Speicher sind als wiederherstellbar definiert.

Andernfalls schreibt CICS eine Nachricht, die den Grund für die Beendigung des Programms angibt. Ein erneut gestartetes Programm ist ein Programm, das vom Beginn der zuletzt ausgeführten Transaktion an wieder gestartet wird. Alle Änderungen an Datenbanken, die seit der letzten Terminierung des PSB des Programms vorgenommen wurden, werden rückgängig gemacht.

Die verteilte Version des CICS-Programms für Neustart (DFHRTY) startet kein mit EGL generiertes Programm vom Beginn der zuletzt ausgeführten Datenbanktransaktion erneut. Sie können entsprechenden Code zu DFHRTY hinzufügen, um EGL-Datenbanktransaktionen erneut zu starten. Ihr Programm muss überprüfen, ob die folgenden Bedingungen erfüllt sind:
  • Der aktuelle Code für abnormale Beendigung ist ADLD.
  • Die Transaktions-ID ist die ID der Transaktion, die erneut gestartet werden soll.
  • Der Zähler für Neustart ist kleiner als die angegebene Zahl. Dies ist eine Schleifenprüfung für Neustart.
Werden alle Prüfungsbedingungen erfüllt, muss Ihr Programm das Flag für Neustart auf aktiviert (ON) setzen, um anzugeben, dass CICS den Neustart fortsetzen soll. Weitere Informationen zum Ändern von DFHRTY finden Sie in den Handbüchern zum Thema Wiederherstellung, Neustart und Anpassung für Ihr CICS-System.

Wenn ein Neustart angefordert wird, müssen für Programme, die im Segmentmodus (pseudodialogfähigem CICS-Modus) ausgeführt werden, alle zu aktualisierenden CICS-Ressourcen als wiederherstellbar definiert sein. Die Namen der Warteschlangen für temporären Speicher, die von der Segmentierungsfunktion von Rational COBOL Runtime erstellt werden, bestehen aus der Terminal-ID für den Benutzer, die an ein aus vier Zeichen bestehendes Präfix angehängt ist. Die verwendeten Präfixe haben das Format X'EE', gefolgt von WRK oder MSG.

Für nicht segmentierte Programme (im interaktiven CICS-Modus) sollte nur dann ein Neustart angefordert werden, wenn das Programm für die Bearbeitung von Neustarts konzipiert wurde. Eine einfache Methode besteht darin, das Programm bei jedem Start folgenden Test durchführen zu lassen: dliVar. cicsRestart. Ist das Flag für Neustart aktiviert (ON), sollte Benutzer 1 eine spezielle Nachricht oder ein spezielles Formular mit folgenden Informationen angezeigt werden:
  • Die Transaktion wurde am Beginn erneut gestartet, da Benutzer 2 zur selben Zeit Änderungen an der Datenbank vornahm.
  • Die von Benutzer 1 vorgenommenen Änderungen wurden zurückgesetzt.
  • Das Programm wurde erneut gestartet, um zu verhindern, dass Änderungen verloren gehen.

Zugriff auf verteilte DL/I-Datenbanken

Programme, die unter CICS ausgeführt werden, können auf DL/I-Datenbanken auf fernen Systemen zugreifen, indem ein Basisprogramm aufgerufen wird, das auf dem System ausgeführt wird, auf dem sich die betreffende Datenbank befindet.


Feedback