[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Oct 2016
    Beiträge
    24

    Umstellung von Chain auf setll + reade - seitdem dauernd Satzsperren

    Hallo ,

    momentan unterstütze ich einen Kollegen in einem anderen Bereich und stoße dauernd auf ein Problem wo ich mich frage wie kann das sein.

    Mein Kollege hat vor ein paar Wochen einen Chain auf ein setll mit reade umgebaut, dahinter folgt dann eine while Schleife mit abfrage bis eof logische datei. In der Schleife selber werden dann noch ein paar andere chain ausgeführt.

    Mit dem Chain klappte alles wie es soll, es gab kein Probleme. Nun seit dem Umbau mit setll und reade läuft das Programm dauernd aus MSGW weil ein Satz nicht zugeordnet werden konnte.

    Ich frage mich nun wie kommt es dazu? Ich muss dazu sagen das ich mich mit Chains und Setll nicht besonders gut auskenne, da ich eigentlich alles mit SQL mache, aber ich meine mal gehört zu haben das eigentlich der chain sperren soll - wie es dann zu einer Sperrung mit setll, also der reinen positionierung, kommen kann verstehe ich nicht.

    Weis vllt. jemand Rat ?
    Das ist ein uralt Programm und der ursprünglich Entwickler ist leider nicht mehr verfügbar und der jetzige Betreuer ist im Urlaub.

    Hier der aktuelle Code :
    Code:
       #K_MdeGrBVL06.GrBVPer   = GrVPer ;
        #K_MdeGrBVL06.GrBVHcNr  = GrVHcNr;
        #K_MdeGrBVL06.GrBVLgNr  = GrVLgNr;
         #K_MdeGrBVL06.GrBVNeNr  = GrVNeNr;
         #K_MdeGrBVL06.GrBVLfdNr = GrVLfdNr;
         setll  %KDs(#K_MDEGrBVL06:5) MdeGrBVL06;
         reade %KDs(#K_MDEGrBVL06:5) MdeGrBVL06;
         dow not %eof(MdeGrBVL06);
            $Index += 1;
             UrsKyGpU = GrBVBSl;
              Chain UrsKyGpU MdeUrsaL01;
               If %Found(MdeUrsaL01) And UrsKyFt > *Zero;
                 $Funktion(UrsKyFt) = *On;
                 $Last = UrsKyFt;
               EndIf;
              Chain GrBVBSl MdeMassL01;
               If %Found(MdeMassL01) And MasKyFt > *Zero;
                 $Funktion(MasKyFt) = *On;
                 $Last = MasKyFt;
               EndIf;
               if $Funktion(9) or  $Funktion(16);
                 exsr #R_BemAutomatischAbarbeiten; // <---hier Update auf MDEGRBVL06
               endif;
               reade %KDs(#K_MDEGrBVL06:5) MdeGrBVL06;
             EndDo;
    Ich bin für jede Hilfe dankbar.

    Viele Grüße
    "Mit dem ersten Glied ist die Kette geschmiedet. Wenn die erste Rede zensiert, der erste Gedanke verboten, die erste Freiheit verweigert wird, dann sind wir alle unwiderruflich gefesselt." - Cpt. Jean-Luc Picard

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Das kannst du am besten dann sehen, wenn der Fehler (MSGW) auftritt, welcher Satz denn da aktuell geblockt ist (WRKJOB->Satzsperren).
    Wenn du über verschiedene LF's mit einer Datei arbeitest, hält jede LF ihren Lock, wenn du die Datei für Update eröffnest.
    Ebenso könnte dein aktueller Dateizeiger (für den nächsten READE) in deiner Updateroutine verschoben werden.
    Das hat aber nichts mit der Umstellung von Chain auf Setll/Reade zu tun.

    Zu Cpt. Jean-Luc Picard hatte (ich glaube es war Dieter Nuhr) noch folgende Weisheit:

    "Die intelligenz dieses Planeten ist endlich. Das Problem: Die Bevölkerung wächst...".
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Baldur hat mit seinem Hinweis auf den READE schon den richtigen Hinweis gegeben. Ich vermute, dass dein Problem darin liegt, dass READE versucht, den nächsten Satz immer zu sperren, egal ob der Satz den passenden Key hat oder nicht.
    Also angenommen, du hättest in der Datei die Sätze mit den Schlüsseln 1,2,2,3,3,4, ...
    Du machst einen SETLL auf den Schlüssel 2 und liest dann mit READE (mit passenden Key "2") weiter. Dann würde der READE beim 3. Leseversuch ja schiefgehen (weil der dann gelesene Satz ja den Schlüssel "3" hätte.) Aber bevor der READE schiefgeht, versucht er zunächst, den Satz zu sperren. Wenn das klappt, würde er natürlich erkennen, dass der Satz nicht zu seinem Key gehört und den Satz wieder freigeben. Aber dazu kommt er gar nicht, wenn er den Satz nicht sperren kann.

    Lösung: Immer mit READE(N) lesen und beim Treffer den Satz dann mit Chain lesen!

    Dieter

  4. #4
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    Alle READ-Befehle lesen immer 2 Datensätze, namlich den aktuellen und den nächsten. Wie sollte sonst festgestellt werden können ob %EOF angesetzt werden soll oder nicht. Wenn die Datei als Update-File definiert wurde, wird dadurch nicht nur der aktuelle sondern auch der folgende Datensatz gesprerrt.

    READE mit der Erweiterung (N) bzw. der Operations-Code UNLOCK funktionieren nur, wenn die Verarbeitung nicht unter Commitment Control ausgeführt wird.

    M.E. ist es am sichersten, die Daten zunächst über eine Input-Datei lesen und dann unmittelbar vor dem Update einen CHAIN auf die Update-Datei zumachen.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  5. #5
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    "Alle READ-Befehle lesen immer 2 Datensätze, namlich den aktuellen und den nächsten. Wie sollte sonst festgestellt werden können ob %EOF angesetzt werden soll oder nicht. Wenn die Datei als Update-File definiert wurde, wird dadurch nicht nur der aktuelle sondern auch der folgende Datensatz gesperrt."

    Nun, das würde man ja über die Lesestatistik sowie Lockübersicht feststellen können, wäre mir aber komplett neu. Ich kann bei einem READE immer nur 1 Satzsperre entdecken.
    READ liefert den nächsten Satz in der Folge der Datei (sequentiell, keyed).
    Ohne weitere Angabe liefert das OS über den Filestatus-Block eben EOF oder nicht.

    READE ist eine spezielle RPG/LE-Funktion, die auch mit verkürztem Key funktioniert. Hierfür vergleicht die Runtime die gelesenen Schlüssel mit den gewünschten und setzt EOF dann selbständig. Zusätzlich wird Unlock aufgerufen, falls die Datei für Update geöffnet ist.
    Wenn also kein EOF vom OS gemeldet wird, muss natürlich der Satz gesperrt werden bevor der Vergleich durchgeführt wird, da sonst ja nach dem Vergleich mittels erneutem Read/Chain die Werte schon wieder geändert sein könnten.

    Würde READE 2 Sätze lesen, müsste ja anschließend wieder ein READPE durchgeführt werden (also 3 Reads) um auf den aktuellen Satz zurück zu positionieren, da man diesen ja ohne erneutes Lesen sonst gar nicht updaten könnte (4. Read), was aber defakto seit Erfindung der IO's nicht erforderlich ist.
    Wobei dieses erneute Lesen wieder zu veränderten Werten führen könnte sowie ein READPE gar nicht zu dem gerade gelesenen sondern zu einem neu eingefügten Satz.

    Mehr als 1 Satz zu sperren ist tatsächlich nur unter Commit möglich, und dann auch nur im Modus, ich glaube *CS, der auch gelesene Sätze sperrt. Dies ist aber i.d.R. kein empfohlener Modus, *CHG (Read Commited) ist da eher normal und der sperrt nicht beim Lesen.

    RLA sperrt nur genau 1 Satz beim Lesen, falls die Datei Update ist.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  6. #6
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Wenn also kein EOF vom OS gemeldet wird, muss natürlich der Satz gesperrt werden bevor der Vergleich durchgeführt wird, da sonst ja nach dem Vergleich mittels erneutem Read/Chain die Werte schon wieder geändert sein könnten.
    Ich bin der Meinung, dass IBM dieses Problem mit ein bisschen mehr Aufwand beim Implementieren des READE hätte lösen können: Einfach ohne Sperre lesen und dann nach dem Sperren nochmal gucken, ob der Satz immer noch den passenden Key enthält.

    Dieses Verhalten beim READE hat mich in der Vergangenheit schon oft geärgert. Aber ich muss zugeben, dass IBM es so dokumentiert hat. Also schlecht implementiert, aber gut dokumentiert => Für IBM ist alles OK.

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Das kannst du ja selber ebenso halten, READE(N) ggf. mit Teilkey => Chain mit Gesamtkey.
    Du must nur bedenken, dass zwischen dem READE(N) und Chain der Satz oder Schlüssel sich geändert haben könnten oder bei nicht-Unique sich ein Satz dazwischengeschoben haben könnte.
    Somit bist du nur beim READE mit Lock, falls du die Daten verarbeiten willst, auf der (etwas) sichereren Seite.
    Ansonsten, und das ist ja dann SQL-Like, mach einen READE auf einer Input-LF und dann den Chain mit dem Unique-Key auf der Unique-LF.

    Ich habe aber ebenso auch schon Anwendungen gesehen, die den READE mittles READ und If-Abfragen selber implementiert haben. Allerdings halt auch mit denselben Konsequenzen.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  8. #8
    Registriert seit
    Oct 2016
    Beiträge
    24
    Ich danke euch für die Erklärungen.
    Werde dann mal tiefer in diese nativen RPG Funktionen einsteigen müssen....

    Versuche dann mal eure Vorschläge zu testen.
    "Mit dem ersten Glied ist die Kette geschmiedet. Wenn die erste Rede zensiert, der erste Gedanke verboten, die erste Freiheit verweigert wird, dann sind wir alle unwiderruflich gefesselt." - Cpt. Jean-Luc Picard

  9. #9
    Registriert seit
    Mar 2002
    Beiträge
    5.286
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Mehr als 1 Satz zu sperren ist tatsächlich nur unter Commit möglich, und dann auch nur im Modus, ich glaube *CS, der auch gelesene Sätze sperrt. Dies ist aber i.d.R. kein empfohlener Modus, *CHG (Read Commited) ist da eher normal und der sperrt nicht beim Lesen.
    Meint: einen Satz pro Cursor! Commit level *CHG ist nun mal gerade read uncommited, sprich: lies jeden Schmutz und nur für Auswahl Subfile Anzeigen zu gebrauchen. Sperrlevel *CS liest zwar nur gültige Sätze (read commited), gibt den Satz aber frei, wenn der nächste gelesen wird und der Satz nicht geschrieben wurde. Sperrlevel *ALL ist das, was der Standard unter cursor stability versteht: keine uncommited reads, gelesene Sätze bleiben bis Transaktionsende gesperrt, unabhängig davon ob sie geändert wurden.

    Für das diskutierte Beispiel wäre Sperrlevel *ALL und Verarbeitung mit SQL Cursor mit where clause angemessen!!! Die Teilauswahl wird verarbeitet wie ein Satz, Sätze außerhalb der Auswahl werden nicht gesperrt (weil nicht gelesen).

    D*B,

    der vehement zum Einsatz von Commit rät!!! Umstellung auf SQL ohne Commit ist ein ernsthafter Fehler, (fast) immer und (fast) überall!!!
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  10. #10
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Ich wollte ja auch nur auf diese Neuheit "Alle READ-Befehle lesen immer 2 Datensätze..." eingehen, muss wohl irgendwie für V8R5 geplant sein um auch wirklich den Letzten von der AS/400 zu vertreiben weil dann nichts mehr geht.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  11. #11
    Registriert seit
    Mar 2002
    Beiträge
    5.286
    ... das war doch ein Missverständnis, in Wirklichkeit wird jeder Satz zweimal gelesen, erst mit RLA, dann mit SQL und dann verglichen, ob man richtig gelesen hat, wenn man den neuesten Buschtrommeln aus Rochester Glauben schenkt...
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

Similar Threads

  1. Programmabsturz bei SETLL auf Join-Logische Datei
    By harkne in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 13-03-17, 12:53
  2. SQL Ersatz für SETGT/READE Kombi
    By mwithake in forum NEWSboard Programmierung
    Antworten: 14
    Letzter Beitrag: 22-06-15, 16:44
  3. Dateifelder sind nach erfolgreichem CHAIN nicht gefüllt
    By harkne in forum NEWSboard Programmierung
    Antworten: 6
    Letzter Beitrag: 19-11-13, 11:02
  4. READ / READE in free-rpg
    By Gimli in forum IBM i Hauptforum
    Antworten: 6
    Letzter Beitrag: 10-03-03, 13:08
  5. Euro-Umstellung in RPG/II
    By Sunny in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 17-04-01, 08:00

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •