[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    May 2004
    Beiträge
    394

    Problem mit Commitsteuerung

    Hallo zusammen,

    ich habe folgendes Problem.

    Programm 1 (CLP) macht einen STRCMTCTL LCKLVL(*CHG) CMTSCOPE(*JOB)
    Programm 1 ruft im Anschluss Programm 2 (RPGLE) auf
    Programm 2 macht verschieden UPDATES auf Dateien die unter COMMIT laufen und kehrt zurück
    Programm 1 macht COMMIT
    Programm 1 ruft jetzt Programm3 (CLP) auf
    Programm 3 versucht zunächst einen STRCMTCTL LCKLVL(*CHG) CMTSCOPE(*ACTGRP) der ja nicht ausgeführt wird da bereits ein STRCMTCTL ausgeführt wurde.
    Programm 3 ruft jetzt Programm4 (RPGLE) auf
    Programm4 macht mehrere UPDATES und bricht dann aber wegen Fehler ab. Die *PSSR wird mit ENDSR RETURN (RETURN=*CANCL) beendet so dass er im Programm3 einen MONMSG erhält.
    Programm3 fragt mit MONMSG ab ob das Programm abgebrochen ist und macht dann einen ROLLBACK und einen ENDCMTCTL (ich weiß, das ist nicht sauber, denn der ENDCMTCTL in dem Programm sollte ja nur gemacht werden wenn das Programm einen STRCMTCTL macht)

    So jetzt aber das Problem. Der ENDCMTCTL stürzt ab weil er sagt dass er offene COMMIT-Sätze hat. Warum fährt er beim ROLLBACK, der genau 2 Anweisungen zuvor war, nicht alles sauber zurück?

    PHP-Code:
    Die Aufrufebene oben ist so
    PGM 1 STRCMTCTL
      PGM 2  updates
    PGM 1 COMMIT
      PGM 3
        PGM 4  Änderungen und Abbruch
      PGM 3 ROLLBACK
      PGM 3 ENDCMTCTL 
    <- Absturz wegen offener COMMITS 
    Habe ich ein Problem damit dass PGM2 zwar mit *LR beendet wird und somit die Datei eigentlich zu schliessen hat, dies aber nicht macht weil erst im CL der COMMIT durchgeführt wird? Somit die Datei immer noch offen ist bzw. für COMMIT zurgeordnet ist und PGM3 deshalb keinen ENDCMTCTL machen darf sondern dies nur PGM1 machen darf?

    Ich habe keine Ahnung :-)

    Viele Grüße Harald

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    19.323
    Also STRCMTCTL sollte man nicht zwischen *JOB und *ACTGRP mischen.
    Wenn ich z.B. in einem Serviceprogramm mit Named ACTGRP erwarte, eine eigene Commitumgebung zu haben, würde dies den Ablauf vollkommen zerstören.

    Rufe ich ein ILERPG mit SQL auf, wird standardmäßig eine Commitgruppe für die ACTGRP eröffnet, falls noch keine vorhanden ist.
    Also muss ich auch da selber auf Transaktionen achten.
    Nur wenn ich explizit ACTGRP(*CALLER) angebe, kann ich mich (vielleicht) auf die Commitsteuerung des rufenden Programmes verlassen.
    Das kommt aber auf das gewünschte Design an.

    Du kannst übrigens mit DSPJOB=>16 die offenen Commitgruppen ansehen.

    Zusätzlich hat der Open-Status einer Datei nichts mit offenen Commits zu tun.
    Ein Close bleibt ein Close.
    Nur SQL verwaltet seine ODP's etwas anders.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: http://www.fuerchau.de/software/upload400.htm
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    May 2004
    Beiträge
    394
    Also das mit dem Mischen gebe ich Dir vollkommen recht, deshalb habe ich ja geschrieben dass es nicht sauber ist, aber das kommt ja an der Stelle nicht zum Tragen, da er den 2. STRCMTCTL gar nicht macht da ja der 1. noch aktiv ist. Das mit DSPJOB Auswahl 16 hätte ich gerne gemacht, das war aber ein Batchjob und bis ich mich darum gekümmert habe, hatte den schon jemand beantwortet. Ich habe es dann versucht so nachzubauen, dass ich den Absturz wieder hin bekomme. Hat aber leider nicht funktioniert. Ich finde es persönlich auch schlecht, dass der ENDCMTCTL im inneren Programm die Commit-Steuerung beendet obwohl er den STRCMTCTL gar nicht gemacht hat. Aber bei uns laufen so viele Programme so, die möchte ich nicht alle ändern.

    Aber Danke für die Hinweise.
    ACTGRP(*CALLER) haben wir standardmäßig in allen ILE-RPG Programmen, außer in denen in denen wir einen rekursiven Aufruf brauchen. Das PGM2 in meiner Auflistung ist ein SQLRPGLE. Allerdings werden nur SELECTs ausgeführt keine Dateiänderungen über SQL.

    Was meinst Du mit einer Commitgruppe? Wenn oben also PGM2 ein SQLRPGLE ist und PGM4 ist ein RPGLE und ich mache im RPGLE einen COMMIT oder ROLLBACK, wären dann die Sätze aus dem PGM2 nicht festgeschrieben?

    Viele Grüße Harald

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    19.323
    Jede ACTGRP ist eine eigene Commitgruppe.
    Der ENDCMTCTL löscht die aktive Commit-Definition, entweder der aktiven ACTGRP oder eben des Jobs.
    Was allerdings nicht heißt, dass die ACTGRP's nicht trotzdem separate Commit-Gruppen sind.
    Mittels STRCMTCTL wird ja nur die Aufzeichnung gestartet, was wie gesagt die SQL-Runtime der Programme aber auch tut.
    Wenn nun aber für eine ACTGRP noch ein offener Commit aktiv ist, kann auch für den Job kein ENDCMTCTL durchgeführt werden, es ist ein Commit/Rollback erforderlich.

    Übrigens: Rekursive Programme funktionieren in ILE auch per "ctl-opt main(MainProc);".
    D.h., der Overhead des Zyklus einfällt, man startet mit einer Mainprozedur, die eben auch rekursiv aufgerufen werden kann und somit auch zur selben ACTGRP gehören kann.

    Eine Transaktion läuft generell in einer ACTGRP von der ersten Aktion (außer Select) bis zum Commit/Rollback auch über mehrere Programme/Serviceprogramme hinweg.
    Der Commit ist auch nicht SQL-spezifisch. Es ist also egal, ob du "exec sql commit;" oder nur "commit;" aufrufst. Wenn STRCMTCTL nicht gestartet ist liefert ersteres einen SQLCODE/SQLSTATE und letzteres eine RPG-Exception.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: http://www.fuerchau.de/software/upload400.htm
    BI? Da war doch noch was: http://www.ftsolutions.de

  5. #5
    Registriert seit
    May 2004
    Beiträge
    394
    Du schreibst:
    Wenn nun aber für eine ACTGRP noch ein offener Commit aktiv ist, kann auch für den Job kein ENDCMTCTL durchgeführt werden, es ist ein Commit/Rollback erforderlich.
    Ich habe folgendes. Ich mache den STRCMTCTL mit *JOB nicht *ACTGRP. Wenn dann ein SQLRPGLE aufgerufen wird, erstellt der eine neue Commit-Gruppe?
    Ich habe den ROLLBACK genau 2 Anweisungen vor dem ENDCMTCTL gemacht und er ist abgestürzt wegen offener Einträge. Das ist genau das was ich nicht verstehe.

    Deswegen auch meine Frage ob es Probleme macht bei folgender Verschachtelung

    CLP1 --> STRCMTCTL *JOB
    CLP1---> ruft auf SQLRPGLE mit UPDATES allerdings nicht mit UPDATES via SQL sonder CHAIN/UPDATE
    CLP1--> COMMIT
    CLP1---> ruft auf CLP2
    CLP2---> ruft auf RPGLE mit Updates
    CLP2---> ROLLBACK
    CLP2---> ENDCMTCTL --> Absturz wegen offen stehender Commits

    Nur genau so wie ich es schreibe habe ich es auch gemacht und da hatte ich keine Probleme.

    Hmm vielleicht muss ich noch schreiben warum das ganze überhaupt zum Absturz kam. Vielleicht liegt darin das Problem

    Das RPGLE was aus CLP2 aufgerufen wurde ist abgestürztm, weil er auf einen Satz zugreifen wollte der von einem anderen Programm gesperrt war. Das andere Programm wollte wiederum in der selben Datei auf einen Satz zugreifen was von dem RPGLE bereits vorher verarbeitet wurde und gesperrt war. Somit haben sie sich gegenseitig gesperrt bis das eine dann abgestürzt ist. Allerdings hat er beim ROLLBACK keinen Fehler gebracht erst beim ENDCMTCTL das noch was offen ist.

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    19.323
    Betrachte dann bitte die Aktivierungsgruppen bzw. die Commit-Gruppen des Jobs.
    Hinzu kommt natürlich, dass Satzsperren bis zum commit bestehen bleiben.
    Da in SQL immer dieselbe Datei nur 1x geöffnet wird (ODP => Open Data Path), ist das kein Problem.
    Bei Datei-Open ist es aber schon immer so, dass hier jeder Open eigene Sperren setzt.

    Prüfe also bitte noch mal die Commit-Definitionen des Jobs zu jedem Zeitpunkt.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: http://www.fuerchau.de/software/upload400.htm
    BI? Da war doch noch was: http://www.ftsolutions.de

  7. #7
    Registriert seit
    May 2004
    Beiträge
    394
    Danke,

    aber an einem Punkt muss ich dann doch nochmal nachfragen

    Da in SQL immer dieselbe Datei nur 1x geöffnet wird (ODP => Open Data Path), ist das kein Problem.
    heißt das, dass wenn ich ein Programm am Laufen habe was unter Commit ein SQL-UPDATE gemacht hat aber noch keinen COMMIT ausgeführt hat, dass in dieser Zeit kein anderes Programm was die selbe Datei unter Commit hat auf die Datei via SQL zugreifen kann oder kein anderes Programm was die selbe Datei unter Commit hat die Datei via SQL updaten kann?

  8. #8
    Registriert seit
    Feb 2001
    Beiträge
    19.323
    Das ist korrekt und Sinn der Transaktion.
    Eine Transaktion soll ja sicherstellen, dass diese Daten in sich konsistent bleiben.
    Daher gibt es eine ungeschriebene Regel:
    Keine Transaktion darf über eine Userinteraktion hinaus gehen um Ressourcen zügig wieder frei zu geben.
    Warum? Du könntest einen Rollback machen und die Änderungen anderer wären dann auch weg.

    Transaktionen sind die kleinsten gemeinsamen Aktionen, die eine Aktivität zu einer unteilbaren Einheit verbindet.
    Z.B.: Auftragsposition erstellen/anpassen/löschen + Bestandsreservierung.
    Eine komplette Auftragserfassung sind daher mehrere Transaktionen.
    Z.B.: Rechnung schreiben: Alle Aktivitäten der einzelnen Rechnung sind eine Transaktion, da die Rechnung unteilbar ist.
    Usw., usf., etc, bla, bla, bla!

    Daher kann ich mir nun nicht vorstellen, dass eine Transaktion über mehrere Programmschritte geht (da sind Services nicht mit gemeint, da diese ja innerhalb der Transaktion benötigt werden).
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: http://www.fuerchau.de/software/upload400.htm
    BI? Da war doch noch was: http://www.ftsolutions.de

  9. #9
    Registriert seit
    May 2004
    Beiträge
    394
    @Fuerchau. Ich brauche jetzt zum Verständnis nochmal ein abnicken.

    Gehen wir von Aufträgen und Auftragspositionen aus

    In den nachfolgenden Fällen wurde vorher ein STRCMTCTL gemacht


    Beim normalen READ/CHAIN und UPDATE

    Wenn ich Auftrag 1 mit Position 1 und 2 geschrieben habe, habe ich auf diese Sätze eine Sperre solange bis ich den COMMIT oder ROLBK ausführe.

    Ein ganz anderes Programm (oder aber auch das selbe Programm von einer anderen Sitzung aus aufgerufen) was auch unter commit läuft kann dann problemos auf Auftrag 2 zugreifen und dort was ändern. Hält natürlich dort die Sperren auch bis ein COMMIT oder ROLBK erfolgt.

    Wenn ich das jetzt richtig verstanden habe verhält es sich aber bei SQL anders
    Wenn also Programm 1 jetzt mit SQL SELECT, UPDATE arbeiten würde und ich hätte einen UPDATE auf einen oder mehrere Sätze des Auftrags 1 gemacht ohne einen COMMIT auszuführen. Dann könnte ein anderes Programm (oder eben wieder dieses von einer anderen Sitzung aus) gar nicht auf die Datei via SQL zugreifen und/oder keine UPDATES machen. Egal ob dieses dann den UPDATE auf Auftrag 2 machen wollte?

    Habe ich das richtig verstanden?

    Das heißt im Falle von SQL habe ich den Vorteil dass ich keine konkurierenden Locks erzeugen kann, dafür aber wahrscheinlich etwas länger warten muss bis die Datei wieder frei ist?

    Viele Grüße Harald

  10. #10
    Registriert seit
    Feb 2001
    Beiträge
    19.323
    Nein hast du leider nicht verstanden.
    Du must unterscheiden zwischen Programmen in derselben Sitzung und verschiedenen Sitzungen.
    Jede Sitzung hat eine eigene SQL-Umgebung und weiß nichts von einer anderen.
    In einer Sitzung hat jede ACTGRP ihre eigene SQL-Umgebung und weiß nichts von der Anderen.

    Jede SQL-Umgebung hält Update/Insert/Delete-Sperren auf Satzeben je Datensatz.
    Somit kann jede SQL-Umgebung auf andere Datensätze derselben Tabelle eintsprechende Aktionen durchführen (der SQL-Server macht das auch gerne anders, nicht aber die DB2).
    Sämtliche Ressourcen werden mit commit bestätigt und freigegeben, mit rollback zurückgedreht aund ebenso freigegeben.

    Innerhalb einer SQL-Umgebung wird jede Tabelle genau nur einmal geöffnet, egal wievele SQL's auf die Tabelle in derselben ACTGRP gemacht werden.

    Native Dateien (PF/LF) werden mit Open von jedem Programm geöffnet. Bei Calls und Open derselben Datei bekommt man einen 2. Open.
    Ausnahme mit SHARE(*YES) bleibt der 1. Open und wird nur hochgezählt. Dies ist aber manchmal schwierig, da ein 1. Open Input mit einem 2. Open Input/Output dann in die Hose geht.
    Satzsperren sind dann auf jeder geöffneten Datei separat möglich.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: http://www.fuerchau.de/software/upload400.htm
    BI? Da war doch noch was: http://www.ftsolutions.de

  11. #11
    Registriert seit
    May 2004
    Beiträge
    394
    OK. Ich war ein klein wenig erschrocken wegen dem wie ich es verstanden hatte.

    Vielen Dank.

Ähnliche Themen

  1. SQL Problem
    Von woodstock99 im Forum NEWSboard Programmierung
    Antworten: 10
    Letzter Beitrag: 23-02-21, 08:38
  2. DDS Problem
    Von KingofKning im Forum NEWSboard Programmierung
    Antworten: 7
    Letzter Beitrag: 15-12-17, 13:20
  3. RPG Problem
    Von Mädele im Forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 22-11-02, 17:06
  4. SQL Problem
    Von HoScHiE im Forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 03-06-02, 13:30
  5. SQL-Problem
    Von chrisi im Forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 27-02-02, 08:46

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •