[NEWSboard IBMi Forum]
Seite 2 von 3 Erste 1 2 3 Letzte
  1. #13
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von dschroeder Beitrag anzeigen
    Ich hätte gerne eine Sperre, die so arbeitet als hätte ich den Datensatz mit chain oder read gelesen.

    Wenn ich einen Datensatz mittels SQL sperre, möchte ich natürlich, dass alle Programme, die den Datensatz noch mit "altem" read oder chain lesen, diese Sperrung beachten.

    Zu unserem selbstgebauten Locking: Da wird einfach in einer Locktabelle für jeden zu sperrenden Datensatz ein Eintrag mit dem Dateinamen und der Record-ID des Datensatzes erzeugt. Jedes Programm, das den Datensatz sperren möchte, guckt vorher in dieser Tabelle nach, ob der Satz bereits von einem anderen Job blockiert wurde. Das Verfahren ist simpel und funktioniert natürlich nur, wenn sich alle an dieses Verfahren halten. Ein Programm, das dieses Verfahren nicht beachtet und sich einfach auf physische Datenbanklocks verlässt, erkennt so eine "logische" Sperrung natürlich nicht.
    ... genau das tut das skizzierte Verfahren.

    ... wobei eure logischen Sperren auch dann nicht funzen, wenn ein Programm mit Sperre stirbt und/oder die Sperre nicht wegmacht. (Das mit dem Absturz kann man natürlich heilen, mit Exit Handler)
    Und wenn man das SQL in eine Lesefunktion zentralisiert, geht das logische auch mit SQL.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  2. #14
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Bei SQL basierten Zugriffen verwenden wir in der Regel Zugriffsmodule, die lesen, schreiben, sperren, und löschen. Wenn ein Job, der eine Sperre eingetragen hat, nicht mehr aktiv ist, gilt die Sperre nicht mehr und wird automatisch aufgeräumt.

    Aber zu den Datenbanksperren mit SQL: Ich komme also nicht drum herum, Programme, in denen ich SQL-Sperrungen haben möchte, speziell zu kompilieren. Ist etwas unschön, aber was will man machen ...

    Vielen Dank für eure Antworten. Ich drohe schon mal damit, demnächst vielleicht mit weiteren Fragen dazu auf das Forum zuzukommen.

    LG, Dieter

  3. #15
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von dschroeder Beitrag anzeigen
    Bei SQL basierten Zugriffen verwenden wir in der Regel Zugriffsmodule, die lesen, schreiben, sperren, und löschen. Wenn ein Job, der eine Sperre eingetragen hat, nicht mehr aktiv ist, gilt die Sperre nicht mehr und wird automatisch aufgeräumt.

    Aber zu den Datenbanksperren mit SQL: Ich komme also nicht drum herum, Programme, in denen ich SQL-Sperrungen haben möchte, speziell zu kompilieren. Ist etwas unschön, aber was will man machen ...

    Vielen Dank für eure Antworten. Ich drohe schon mal damit, demnächst vielleicht mit weiteren Fragen dazu auf das Forum zuzukommen.

    LG, Dieter
    ... da gibt es nix mit anders koompilieren, das kann man in der Quelle mit sql options regeln. Ich rate allerdings dazu, das dann richtig zu machen.
    1.) den Unfug mit dem geänderten command default beim CRTSQLRPGI abzustellen und den COMMIT(*NONE) in die SQL Options zu stellen.
    2.) Dann werden die obigen Programme simple mit default gewandelt.
    3.) Das Commit(*NONE) richtigstellen und mit commit arbeiten.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  4. #16
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von BenderD Beitrag anzeigen
    ... da gibt es nix mit anders koompilieren, das kann man in der Quelle mit sql options regeln. Ich rate allerdings dazu, das dann richtig zu machen.
    1.) den Unfug mit dem geänderten command default beim CRTSQLRPGI abzustellen und den COMMIT(*NONE) in die SQL Options zu stellen.
    2.) Dann werden die obigen Programme simple mit default gewandelt.
    3.) Das Commit(*NONE) richtigstellen und mit commit arbeiten.

    D*B
    Das klingt gut. Vielen Dank!
    Ich werde das mal ausprobieren.

    Schönen Abend an alle.

  5. #17
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Du kannst ja nach dem Fetch des For-Update-Cursors einen "update table where current of cursor" durchführen. Der sperrt so lange, wie kein Commit gemacht wird, wenn *CHG verwendet wird.
    Dafür ist es natüürlich wichtig, dass dein Sperrprogramm in einer benannten ACTGRP läuft sonst hebt irgendein Commit im Job deine Sperre auf.
    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. #18
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Du kannst ja nach dem Fetch des For-Update-Cursors einen "update table where current of cursor" durchführen. Der sperrt so lange, wie kein Commit gemacht wird, wenn *CHG verwendet wird.
    Dafür ist es natüürlich wichtig, dass dein Sperrprogramm in einer benannten ACTGRP läuft sonst hebt irgendein Commit im Job deine Sperre auf.
    ... unter commit kriegst du eine ausreichende Sperre erst mit dem update. Bei change sperrt der read überhaupt nicht. Ohne commit sperrt der for update cursor schon beim read, welche Sperre der genau setzt, habe ich nicht parat - ich arbeite grundsätzlich immer mit commit, weil das Stand der Technik ist und damit erforderlich für Revisions sichere Programme.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  7. #19
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von dschroeder Beitrag anzeigen
    Zu unserem selbstgebauten Locking: Da wird einfach in einer Locktabelle für jeden zu sperrenden Datensatz ein Eintrag mit dem Dateinamen und der Record-ID des Datensatzes erzeugt. Jedes Programm, das den Datensatz sperren möchte, guckt vorher in dieser Tabelle nach, ob der Satz bereits von einem anderen Job blockiert wurde. Das Verfahren ist simpel und funktioniert natürlich nur, wenn sich alle an dieses Verfahren halten. Ein Programm, das dieses Verfahren nicht beachtet und sich einfach auf physische Datenbanklocks verlässt, erkennt so eine "logische" Sperrung natürlich nicht.
    ... noch eine Bemerkung zu eurem Sperrverfahren:
    Ich würde hier Satzsperren und Prozesssynchronisation gedanklich voneinander trennen. Satzsperren sind kurz andauernd (Milllisekunden) und dienen der Transaktionskontrolle, das macht die Datenbank automatisch und hier dürfen keine lang andauernden (mehar als eine Bildschirmtransaktion) Sperren auftreten.
    Prozesssynchronisation benötigt lang andauernde Sperren, bis ein anderer Prozess fertig ist. Hierunter fallen z.B.: Reisebuchungen, Verwaltung von Versicherungsverträgen können dazu gehören, auch Bestellungen mit Reservierungen können dazu gehören; in dieselbe Kategorie fallen auch etliche Batchprogramme (während Verbuchung A läuft, dürfen manche Prozesse nicht laufen), insbesondere bei Parallelisierung (wg. Speed).
    Euer Ansatz mit einer Datei, die Sperren verwaltet ist erst mal OK. Ich würde das allerdings optimieren.
    - Sperre setzen durch schreiben eines Sperrsatzes unter commit in einer ACTGRP, die nie commited wird.
    - Sperre freigeben durch löschen des Sperrsatze.
    - bricht das irgendwo ab, macht die Datenbank einen automatischen Rollback (hackt jemand die Stromzufuhr durch, beim nächsten IPL)
    - zentralisiert wird das in einem SRVPGM, das als einziges die Sperrdatei benutzt und dazu aufgerufen wird. Beim CRTSRVPGM ACTGRP(NOCOMMIT) verwenden.
    - kann eine Sperre nicht erteilt werden, sendet die entsprechende Procedure eine Abbruchmeldung.
    - optional kann man noch einen wait Parameter in die Schnittstelle aufnehmen, bei immed sendet man eine Escape Message - ansonsten blockiert man den aufrufenden Prozess (lässt ihn warten).
    Die Sperrdatei wird mit recordwait immed angelegt.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  8. #20
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von BenderD Beitrag anzeigen
    ... noch eine Bemerkung zu eurem Sperrverfahren:
    Ich würde hier Satzsperren und Prozesssynchronisation gedanklich voneinander trennen. Satzsperren sind kurz andauernd (Milllisekunden) und dienen der Transaktionskontrolle, das macht die Datenbank automatisch und hier dürfen keine lang andauernden (mehar als eine Bildschirmtransaktion) Sperren auftreten.
    Prozesssynchronisation benötigt lang andauernde Sperren, bis ein anderer Prozess fertig ist. Hierunter fallen z.B.: Reisebuchungen, Verwaltung von Versicherungsverträgen können dazu gehören, auch Bestellungen mit Reservierungen können dazu gehören; in dieselbe Kategorie fallen auch etliche Batchprogramme (während Verbuchung A läuft, dürfen manche Prozesse nicht laufen), insbesondere bei Parallelisierung (wg. Speed).
    Euer Ansatz mit einer Datei, die Sperren verwaltet ist erst mal OK. Ich würde das allerdings optimieren.
    - Sperre setzen durch schreiben eines Sperrsatzes unter commit in einer ACTGRP, die nie commited wird.
    - Sperre freigeben durch löschen des Sperrsatze.
    - bricht das irgendwo ab, macht die Datenbank einen automatischen Rollback (hackt jemand die Stromzufuhr durch, beim nächsten IPL)
    - zentralisiert wird das in einem SRVPGM, das als einziges die Sperrdatei benutzt und dazu aufgerufen wird. Beim CRTSRVPGM ACTGRP(NOCOMMIT) verwenden.
    - kann eine Sperre nicht erteilt werden, sendet die entsprechende Procedure eine Abbruchmeldung.
    - optional kann man noch einen wait Parameter in die Schnittstelle aufnehmen, bei immed sendet man eine Escape Message - ansonsten blockiert man den aufrufenden Prozess (lässt ihn warten).
    Die Sperrdatei wird mit recordwait immed angelegt.

    D*B
    Guten Morgen,
    unser Sperrverfahren läuft in etwa so, wie du es skizziert hast, denke ich. Der Satz in der Sperrdatei wird mit einem physischen Lock versehen. Zugegebenermaßen noch mit F-Bestimmung. Es gibt auch nur ein zentrales Tool, das die Sperren verwaltet.

  9. #21
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Hallo Baldur und D*B,
    ihr habt ja beide das Verfahren update table where current of cursor genannt. Ich habe dazu mal gerade etwas in der IBM-Doku gelesen. Im IBM Beispiel dazu steht:
    DECLARE THISEMP CURSOR FOR
    SELECT EMPNO, LASTNAME,
    WORKDEPT, JOB
    FROM CORPDATA.EMPLOYEE
    FOR UPDATE OF JOB

    Meine Frage hierzu ist: Was bedeutet "OF JOB" ? Heißt das, dass ich schon beim Deklarieren des Cursors das Feld angeben kann (oder muss?), welches ich später updaten möchte?



  10. #22
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... soweit ich das im Kopf habe, ist die update clause optional.
    Ich habe allerdings wieder mal eine Anmerkung: Entgegen der Empfehlung anderer Kollegen, rate ich immer zum select *, dann kann man nämlich beim fetch in die entsprechende externe DS einlesen (ein unschätzbarer Vorteil der DB2/400). Dieses Verfahren ist narrensicher zur Compilezeit, zur Laufzeit und bei Änderung. Wenn ich denn nur eine Teilauswahl haben will, erledige ich das über eine View (wozu ich ohnehin stets rate).

    D*B

    PS: ich habe mal beim fetch in einer ellenlangen Feldliste zwei Felder vertauscht. Der Fehler ist erst aufgefallen, als krumm geschobene Daten aufgefallen sind. Ich habe Tage gesucht und ohne Journale wäre ich halbwegs aufgeschmissen gewesen.
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  11. #23
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Vielen Dank,
    wenn es wenige Felder sind, lesen wir normalerweise ein Feldauswahl. Bei vielen Feldern dagegen lesen wir meistens in die externe Struktur ein.

  12. #24
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Das mache ich:

    Am einfachsten ist ein Service, klar mit eigener geschlüsselter Tabelle.
    Die Tabelle enthält einen Hauptkey, ggf. Mandant, so wie ein allgemeines großes Feld (256 reicht meist) als Sperr-Key. Zusätzlich ein Feld mit dem Job-Bezeichner und aus statistischen Gründen einen Timestamp.
    Der Service läuft in einer eigenen ACTGRP mit Commit *CHG.
    Der Service liefert *on/*off ob eine Sperre erhalten wurde und per Referenz eine Error-Struktur, die den sperrenden Job bezeichnet. Somit kann per "if not GetLock(Mandant : %char(k1) + ',' + %char(k2) : error)" einfach geprüft werden.
    Mittels UnLock(Mandant : %char(k1) + ',' + %char(k2)) wird der Lock entfernt, wenn er dem Job gehört.
    k1 + k2 sind hier Synonyme für variable Schlüsselgestaltung.

    Sperrschleife wegen konkurierender Zugriffe:
    Step 1:
    Read und prüfen per SQL ACTIVE_JOB_INFO
    - Wenn nicht vorhanden, Insert mit Schlüssel eigenem Job und Timestamp
    - Wenn SQLCODE = 0, commit und return *on
    - Wenn doppelter Key, iter in Schleife, anderer war schneller, erforderliche falls anderer Rollback macht.
    - Wenn SQLCODE <> 0, schwerer Fehler, der nicht vorkommen sollte, rollback, return *off
    Step 2:
    - wenn eigener Job oder Job nicht aktiv, update Timestamp, commit return *on
    - wenn Job Aktiv, commit, return *off.

    Im Test auf einer P9 konnte ich ca. 1000 Locks je Sekunde damit durchführen.
    Wenn Programme über Menüs aufgerufen werden, kann man entweder im Menüprogramm oder per Wrapper nach Ende des Programmes einen RemoveAllLocks() des eigenen Jobs machen.

    Aus Sicherheitsgründen erstelle ich noch einen Haupt-Lock um parallele Locks auszuschliessen:
    do *on;
    upddate locktable set locktime = current timestamp;
    wenn sqlcode = 100 => Insert
    wenn sqlcode = 0 => leave
    // grober Fehler
    enddo;

    Somit kann noch sichergestellt werden, dass für die Lockprüfung keiner dazwischen kommt.

    Jedes Programm ist selber dafür verantwortlich, Locks zu setzen und zu entfernen. Auf Grund der Schlüssel kann man beliebig viele Locks setzen.

    1 Mal am Tag werden alle Locks gelöscht, deren Jobs nicht mehr aktiv sind.
    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

Similar Threads

  1. SQL - Wie bekomme ich die Genauigkeit hin?
    By Lucky662 in forum NEWSboard Programmierung
    Antworten: 11
    Letzter Beitrag: 28-07-22, 08:30
  2. [JDBC] Locking/PerformanceProblem
    By LoCal in forum NEWSboard Programmierung
    Antworten: 1
    Letzter Beitrag: 22-07-05, 10:15
  3. wie bekomme ich verschiedene Schriften auf 1 Seite
    By gize in forum NEWSboard Drucker
    Antworten: 6
    Letzter Beitrag: 22-02-05, 06:48
  4. Wie bekomme ich eine SAVF auf die AS400
    By Miles in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 13-10-03, 19:47
  5. Was ******SE und wo bekomme ich es??
    By Arbi in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 22-09-01, 10:13

Berechtigungen

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