View Full Version : OPM und ILE COBOL mischen
Hallo liebes Forum,
ich habe hier eine große Applikation in OPM COBOL und möchte diese um neue Funktionen mit ILE-COBOL ergänzen. Vor einigen Jahren hatte ich das Thema schon mal, damals führter aber der gemischte Aufruf zwischen OPM und ILE zu undefinierbaren Problemen, die Aussage von IBM war damals, ILE und OPM COBOL sollten nicht im gleichen Programmstack laufen. (Nach dem Motto: Kann funktionieren, muss aber nicht) Ich finde leider aktuell dazu keine Informationen.
Gib es hierzu Erfahrungen ?
Danke für Eure Unterstützung
Karsten
Eigentlich gibt es da keine Probleme, wenn man das Thema Run-Unit korrekt betrachtet.
Ich kann OPM aus ILE genauso aufrufen wie umgedreht.
Wichtig ist lediglich die "STOP RUN"-Behandlung.
Beim CRTCBLMOD+CRTPGM oder CRTBNDCBL sollte als ACTGRP ggf. *CALLER verwendet werden (default ist QILE).
Wenn ein OPM-Cobol-Main-Programm endet (STOP RUN / GOBACK), werden alle aktiven OPM-Cobol-Programme mit geschlossen.
Sind ILE-COBOL-Programme aufgerufen worden mit eigener ACTGRP bleiben diese Aktiv (kann natürlich auch Absicht sein).
Ansonsten kann man per RCLACTGRP auch diese aktiven ILE-COBOL's deaktivieren.
Ich meine:
Es funktioniert, wenn man das Beenden korrekt steuern kann.
*Caller aufgerufen aus OPM hat zur Folge, dass das nicht per RCLACTGRP rausgeworfen werden kann.
Solange man keinen Unfug mit OVRDBF, SHARE(*YES) und Konsorten macht (Anmerkung: Unfug ist hier der default und Fug selten), sollte das alles ohne Probleme sein.
Drei Punkte gibt es noch für ILE, die mit OPM/ILE nix zu tun haben.
- Wichtig ist bei ILE, dass man reproduzierbare Compiles hat!
- Bei Einsatz von Commitment Controll ist die ACTGRP von höchster Wichtigkeit
- am einfachsten alles über SRVPGMs binden und immer komplett neu erstellen und binden von Programmen.
D*B
Eigentlich gibt es da keine Probleme, wenn man das Thema Run-Unit korrekt betrachtet.
Ich kann OPM aus ILE genauso aufrufen wie umgedreht.
Wichtig ist lediglich die "STOP RUN"-Behandlung.
Beim CRTCBLMOD+CRTPGM oder CRTBNDCBL sollte als ACTGRP ggf. *CALLER verwendet werden (default ist QILE).
Wenn ein OPM-Cobol-Main-Programm endet (STOP RUN / GOBACK), werden alle aktiven OPM-Cobol-Programme mit geschlossen.
Sind ILE-COBOL-Programme aufgerufen worden mit eigener ACTGRP bleiben diese Aktiv (kann natürlich auch Absicht sein).
Ansonsten kann man per RCLACTGRP auch diese aktiven ILE-COBOL's deaktivieren.
Ich meine:
Es funktioniert, wenn man das Beenden korrekt steuern kann.
- Bei Einsatz von Commitment Controll ist die ACTGRP von höchster Wichtigkeit
Kannst Du das noch etwas erläutern ?
Was ist bei ACTGRP(*Caller) ?
Hallo,
- Bei Einsatz von Commitment Controll ist die ACTGRP von höchster Wichtigkeit
Kannst Du das noch etwas erläutern ?
Der Unterlassungswert beim STRCMTCTL für Commitment Scope ist *ACTGRP, d.h. ein Rollback ist nur innerhalb der gleichen Aktivierungsgruppe möglich.
Arbeitet man mit diesem Default und mehreren Aktivierungsgruppen, kommt es bei Transaktionen, die sich über mehrere Aktivierungsgruppen hinziehen bei einem Rollback zu unerwünschten Ergebnissen, d.h. es wird nicht alles zurückgesetzt.
Aus diesem Grund sollte man, solange man keine echte ILE-Umgebung hat und die Commitment Control nicht ordentlich auf Aktivierungsgruppen-Ebene gesteuert wird den Commitment Scope im STRCMTCTL auf *JOB setzen.
Wurde die Commitment Control nicht gestartet, d.h. der CL-Befehl STRCMTCTL noch nicht ausgeführt und ein SQL-Insert, Update oder Delete unter Commitment Control ausgeführt (unabhängig davon ob STRSQL verwendet wird oder ob das SQL-Statement in einem (Service-)Programm oder einer Stored Procedure ausgeführt wird), wird STRCMTCTL automatisch mit Unterlassungswerten gestartet.
Commitment Control kann innerhalb eines Jobs nur einmalig gestartet werden. Eine Änderung ist nicht möglich, sondern lediglich die Beendigung (mit ENDCMTCTL) und eine erneute Ausführung des STRCMTCTLs.
Birgitta
grundsätzlich muss man unterscheiden zwischen Commitmaster und Commitslaver. Commitmaster ist immer derjenige, der die Transaktion steuert, sprich Commit und Rollback sagt, Committslaves können als eine Art Hilfsprogramme auch updates machen, aber steuern die Transaktion nicht, enthalten also keine Rollbacks oder Commits.
Am einfachsten ist es nun dem Commitmaster eine benamte Aktivierungsgruppe (gleich PGMName, bzw. SRVPGMName) zu verpassen und Commitslaves grundsätzlich mit ACTGRP *CALLER zu erstellen, dann passt alles und jede Transaktion arbeitet so, als ob sie eine eigene Connection zur Datenbank hätte und alle Transaktionen sind voneinander unabhängig.
D*B
Kannst Du das noch etwas erläutern ?
Was ist bei ACTGRP(*Caller) ?
Seit wann wird STRCMTCTL automatisch durchgeführt ?
Bisher war es so, dass der Open mit Fehler abgewiesen wurde, wenn CMTCTL nicht VOR Programmaufruf gestartet wurde.
Ansonsten ist CMTCTL auf Aktivierungsgruppe wirklich nur sinnvoll, wenn diese auf unterschiedliche Tabellen zugreifen, da es sonst innerhalb des Jobs zu Deadlocks kommen kann (o.ä.).
Beispiel:
ACTGRP(Def1) ruft PGMX mit ACTGRP(*CALLER) auf
ACTGRP(Def2) ruft PGMX mit ACTGRP(*CALLER) auf
PGMX versucht nun ggf. Daten zu ändern oder zu sperren, die von der anderen ACTGRP gesperrt sind.
Also auch ACTGRP(*CALLER) kann Probleme verursachen, wenn das Programm aus verschiedenen ACTGRP's verwendet werden kann.
Das weitere Problem ist noch das Journal selber.
Bei CMTCTL(*JOB) können nur Dateien geöffnet werden, die in dem selben Journal aufgezeichnet werden.
Bei CMTCTL(*ACTGRP) kann je ACTGRP ein anderes Journal verwendet werden.
Wichtig in diesem Zusammenhang ist vor allem, wenn man per CONNECT zu einer Remote-DB verbindet.
Wenn ein Programm sowohl lokal als auch remote arbeitet, muss mittels CONNECT ständig hin und her geschaltet werden, was drastisch auf die Performance geht.
Trennt man aber die Aufrufe in 2 verschiedene ACTGRP's, kann die lokale in ACTGRP1 mit dem lokalen Journal arbeiten und die ACTGRP2 mit dem fernen Journal und der fernen DB arbeiten.
Der CALL zwischen ACTGRP's kostet keine messbare Zeit (ist wie EXSR zu vergleichen), und der CONNECT-Wechsel entfällt.
zum Start von Commit unter COBOL kann ich nix beitragen.
zu den Deadlocks muss ich was sagen:
eine Satzsperre ist ein Lock, zum Deadlock wird das erst dann, wenn zyklische Wartebedingungen auftreten, oder bei der Eskalation von Locks (eine üble DB2 Tücke), das hat mit dem Commit Scope auf ACTGRP Ebene nix zu tun. Wenn derselbe Satz in zwei voneinander unabhängigen Transaktionen angefasst wird, dann stimmt die fachliche Logik nicht!!!
Transaktionen bewegen sich innerhalb einer Datenbank und nicht mehreren und die Tabellen einer Datenbank gehören immer in einem Journal journalisiert, wer das anders macht, darf sich über Folgeprobleme nicht beklagen (bin mir nicht mal sicher, ob diese Restriktion nicht mittlerweile gelockert ist).
Der Contextswitch tritt bei meiner Empfehlung nie auf, da man zwei Commitmaster hat und die immer in verschiedenen Aktivierungsgruppen laufen.
Hier gilt wie so oft: Viele Probleme lassen sich durch gutes und einfaches Design vermeiden, Programm technische Komplexität ist oft auf Designmängel zurückzuführen.
D*B
Seit wann wird STRCMTCTL automatisch durchgeführt ?
Bisher war es so, dass der Open mit Fehler abgewiesen wurde, wenn CMTCTL nicht VOR Programmaufruf gestartet wurde.
Ansonsten ist CMTCTL auf Aktivierungsgruppe wirklich nur sinnvoll, wenn diese auf unterschiedliche Tabellen zugreifen, da es sonst innerhalb des Jobs zu Deadlocks kommen kann (o.ä.).
Beispiel:
ACTGRP(Def1) ruft PGMX mit ACTGRP(*CALLER) auf
ACTGRP(Def2) ruft PGMX mit ACTGRP(*CALLER) auf
PGMX versucht nun ggf. Daten zu ändern oder zu sperren, die von der anderen ACTGRP gesperrt sind.
Also auch ACTGRP(*CALLER) kann Probleme verursachen, wenn das Programm aus verschiedenen ACTGRP's verwendet werden kann.
Das weitere Problem ist noch das Journal selber.
Bei CMTCTL(*JOB) können nur Dateien geöffnet werden, die in dem selben Journal aufgezeichnet werden.
Bei CMTCTL(*ACTGRP) kann je ACTGRP ein anderes Journal verwendet werden.
Wichtig in diesem Zusammenhang ist vor allem, wenn man per CONNECT zu einer Remote-DB verbindet.
Wenn ein Programm sowohl lokal als auch remote arbeitet, muss mittels CONNECT ständig hin und her geschaltet werden, was drastisch auf die Performance geht.
Trennt man aber die Aufrufe in 2 verschiedene ACTGRP's, kann die lokale in ACTGRP1 mit dem lokalen Journal arbeiten und die ACTGRP2 mit dem fernen Journal und der fernen DB arbeiten.
Der CALL zwischen ACTGRP's kostet keine messbare Zeit (ist wie EXSR zu vergleichen), und der CONNECT-Wechsel entfällt.
Solange man sich in einer Applikation bewegt ist das ja auch handlebar.
Leider gibt es aber auch manchmal Schnittstellenprogramme zwischen verschiedenen ERP's, die natürlich in jeweils eigenen Journalen aufzeichnen.
Ich muss also z.B. aus ERPA mit JournalA daten lesen, als verarbeitet markieren (unter Commit) und in ERPB mit JournalB schreiben, natürlich auch mit Commit (2-Phase).
Hier hilft tatsächlich nur eine Trennung der Aktionen in 2 ACTGRP's, mit separatem Commit.
Vielleicht gibts ja inzwischen Erweiterungen, so dass ich auch auf der AS/400 ein 2-Phase-Commit über 2 (logische) DB's erreichen kann.
Birgitta sollte uns mehr dazu sagen können.
Zu COBOL sei noch gesagt, dass ich einen OPEN selber codieren muss. Wenn CMTCTL nicht gestartet ist, gibt der Open einen Status raus.
Wenn ich den ignoriere, kommts später dann zu MCH-Fehlern, da ich auf nicht angelegte Puffer zugreife.
Bei RPG/LE gibts bei impliziten oder explizenten Open ohne (E) eine Exception-Nachricht.
Allerdings gibts bei der Definition der Datei sowohl bei RPG als auch COBOL eine unterlassbare Angabe, dass diese Datei unter CMTCTL zu verarbeiten ist.
Ohne Angabe, erfolgt keine Prüfung auf aktives CMTCTL, so dass ggf. das übergeordnete Programm über Commit/Rollback oder nur Journalsierung entscheidet.
das ist dann wieder der Fall mit einem Commit Master, der Rest sind slaves. sprich: alles in einer ACTGRP, bei V5R4 (ab wann genau, findet man in der Reference) ist es der Möhre Wurscht in wievielen Journalen das journalisiert wird, selbst mit remote Datenbanken muss das gehen, wenn alle DUW (distributed Unit of Work) unterstützen. Dann hast du allerdings wieder dein set connection (was wohl nur mit DUW - ist default beim Compile - den entsprechenden Overhead generiert.
Der Master sagt dann am Ende Komm mit (Commit), oder lass es bleiben (Rollback) und die Updates machen dann die entsprechenden Datenzugriffsprogramme als slaves alle mit *CALLER gewandelt.
Sicherlich kann man das alles viel komplizierter machen, wenn man zusätzliche Probleme haben will, wie so vieles bei ILE.
D*B
D*B
Solange man sich in einer Applikation bewegt ist das ja auch handlebar.
Leider gibt es aber auch manchmal Schnittstellenprogramme zwischen verschiedenen ERP's, die natürlich in jeweils eigenen Journalen aufzeichnen.
Ich muss also z.B. aus ERPA mit JournalA daten lesen, als verarbeitet markieren (unter Commit) und in ERPB mit JournalB schreiben, natürlich auch mit Commit (2-Phase).
Hier hilft tatsächlich nur eine Trennung der Aktionen in 2 ACTGRP's, mit separatem Commit.
Vielleicht gibts ja inzwischen Erweiterungen, so dass ich auch auf der AS/400 ein 2-Phase-Commit über 2 (logische) DB's erreichen kann.
Birgitta sollte uns mehr dazu sagen können.
Zu COBOL sei noch gesagt, dass ich einen OPEN selber codieren muss. Wenn CMTCTL nicht gestartet ist, gibt der Open einen Status raus.
Wenn ich den ignoriere, kommts später dann zu MCH-Fehlern, da ich auf nicht angelegte Puffer zugreife.
Bei RPG/LE gibts bei impliziten oder explizenten Open ohne (E) eine Exception-Nachricht.
Allerdings gibts bei der Definition der Datei sowohl bei RPG als auch COBOL eine unterlassbare Angabe, dass diese Datei unter CMTCTL zu verarbeiten ist.
Ohne Angabe, erfolgt keine Prüfung auf aktives CMTCTL, so dass ggf. das übergeordnete Programm über Commit/Rollback oder nur Journalsierung entscheidet.