[NEWSboard IBMi Forum]
Seite 1 von 3 1 2 ... Letzte
  1. #1
    Registriert seit
    Jan 2012
    Beiträge
    1.120

    Wie bekomme ich Record-Locking mit embedded SQL hin?

    Hallo zusammen,

    ältere Teile unserer Software sind noch nicht mit embedded SQL geschrieben, sondern basieren auf satzweisem Zugriff mit F-Bestimmungen.

    Neue Programme schreiben wir ausschließlich SQL-basiert. Für das Record-Locking nutzen wir ein selbstgebautes Locking-Verfahren.

    Es kommt jetzt immer häufiger vor, dass wir ältere Bereiche in Teilen modernisieren. Natürlich ist das alte physische Record-Locking Verfahren nicht mit unserem neuen "logischen" Locking kompatibel. Wir schreiben deshalb immer sehr viele Programme um, die wir fachlich gar nicht umschreiben müssten, nur weil die unterschiedlichen Locking Verfahren sonst nicht miteinander funktionieren.

    Deshalb meine Frage: Kann ich mit einfachen!!! Mitteln auch mit SQL Record-Locking bauen? Wir haben uns mit dem gesamten Komplex des commit control bisher nicht beschäftigt und wir wollen auch nicht alles bei uns umbauen.

    Was ich mit SQL gerne hätte:
    - Satz lesen und physischen Record-Lock setzen. Oder auch in 2 Operationen. Das ist egal.
    - Satz speichern und den Record-Lock wieder aufheben. Ob das direkt geht oder in einem zweiter Schritt eine Art unlock erforderlich ist, ist mir dabei egal.

    Wichtig: Ich möchte dabei möglichst kein großes Risiko eingehen und irgendeinen globalen Schalter setzen, der dafür sorgt, dass sich plötzlich alle SQL-Anweisungen auf dem System anders verhalten. Ich hoffe, es gibt eine Lösung, die "lokal begrenzt" ist.

    Zur Info: Alle unsere Tabellen sind journalisiert.

    Vielen Dank im Voraus.

    LG, Dieter

  2. #2
    Registriert seit
    Feb 2017
    Beiträge
    43
    Hallo,
    sollte es nicht reichen wenn du den Datensatz mit for update liest? Und mit Update gibst du dann wieder frei.

    Gruß,
    Manuel

  3. #3
    Registriert seit
    Nov 2020
    Beiträge
    331
    Du kannst im SQL auch das Commit-Level auf *RR setzen.
    Dann werden alle Sätze die gelesen werden automatisch gesperrt.
    Du musst sie dann halt mit Commit/Rollback wieder freigeben.

  4. #4
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von Andreas_Prouza Beitrag anzeigen
    Du kannst im SQL auch das Commit-Level auf *RR setzen.
    Dann werden alle Sätze die gelesen werden automatisch gesperrt.
    Du musst sie dann halt mit Commit/Rollback wieder freigeben.
    Das hört sich irgendwie gefährlich an.
    Wo müsste ich das denn machen? Ich möchte ja keine globalen Schalter setzen. Wirkt das nur lokal in meinem Programm, das den Daten liest? Was ich gerne hätte, wäre eine Sperrmöglichkeit, die nur von dem gewünschten SQL-Statement genutzt wird. Ich möchte nicht, dass sämtlich anderen SQLs auch irgendetwas sperren.

  5. #5
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von manuel.marcos Beitrag anzeigen
    Hallo,
    sollte es nicht reichen wenn du den Datensatz mit for update liest? Und mit Update gibst du dann wieder frei.

    Gruß,
    Manuel
    Wo kann man das for update denn angeben? Beim declare für einen Cursor?

  6. #6
    Registriert seit
    Nov 2020
    Beiträge
    331
    Genau, das commit wäre für das gesamte Programm gültig.
    Dann wäre sie Variante vom Manuel besser.
    Du kannst einfach beim Deklarieren des Cursors am Ende ein "... for Update" dranhängen.
    Dann ist der gelesene Satz gesperrt, bis du entweder ein Update oder ein Close Cursor machst.

  7. #7
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von Andreas_Prouza Beitrag anzeigen
    Genau, das commit wäre für das gesamte Programm gültig.
    Dann wäre sie Variante vom Manuel besser.
    Du kannst einfach beim Deklarieren des Cursors am Ende ein "... for Update" dranhängen.
    Dann ist der gelesene Satz gesperrt, bis du entweder ein Update oder ein Close Cursor machst.
    Vielen Dank schon mal an euch beide. Ich habe das mal ausprobiert. Aber es scheint nicht zu klappen.

    Hier mein Code:

    Code:
    exec sql declare csr1 cursor for  select * from bvsadres
       where ad_rec_id = 1000000065654 for update;
    
    
    exec sql open csr1;
    
    
    dow sqlcod = 0;
       um_msgbox('vor fetch');
       exec sql fetch next from csr1 into :ADRESSatz;
       um_msgbox('nach fetch' + ' Code ' + %char(sqlcod));
       if sqlcod <> 0;
          leave;
       endif;
    
    enddo;
    
    
    exec sql close csr1;
    um_msgbox('nach close');

    Wenn ich das Programm laufen lassen und z.B. vor oder nach dem Fetch mit DSPRCDLCK bvsadres die Satzsperren auf der Datei anschaue, werden keine Satzsperren angezeigt.

    Muss man vielleicht noch grundsätzlich irgendetwas einstellen, damit das for update wirkt oder sehe ich die Locks mit dem Bordmitteln einfach nicht?

  8. #8
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Doch, das For Update klappt. Du kannst die auch i.d.R. unter DSPJOB => Sperren => Satzsperren sehen.
    Du solltest jedoch Commit=*CHG verwenden, was nur bei Journlisierung klappt.
    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

  9. #9
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von dschroeder Beitrag anzeigen
    Hallo zusammen,


    Was ich mit SQL gerne hätte:
    - Satz lesen und physischen Record-Lock setzen. Oder auch in 2 Operationen. Das ist egal.
    - Satz speichern und den Record-Lock wieder aufheben. Ob das direkt geht oder in einem zweiter Schritt eine Art unlock erforderlich ist, ist mir dabei egal.

    LG, Dieter
    ... was für eine Sperre hättest Du denn gerne?

    Einfach und nahe dran am Rekord Löffel ist:
    - Programm mit commit wandeln
    - dummy update auf Satz
    - Satz lesen
    ... whatever you want
    - freigeben mit commit

    Gegenfrage: was verstehst Du unter "selbstgebautes Locking Verfahren?

    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/

  10. #10
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Doch, das For Update klappt. Du kannst die auch i.d.R. unter DSPJOB => Sperren => Satzsperren sehen.
    Du solltest jedoch Commit=*CHG verwenden, was nur bei Journlisierung klappt.
    Wir haben alle Tabellen journalisiert. Was heißt denn "Du solltest jedoch Commit=*CHG verwenden" ? Kann ich das im Code angeben oder muss ich dazu Programme mit anderen Optionen kompilieren?

  11. #11
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von BenderD Beitrag anzeigen
    ... was für eine Sperre hättest Du denn gerne?

    Einfach und nahe dran am Rekord Löffel ist:
    - Programm mit commit wandeln
    - dummy update auf Satz
    - Satz lesen
    ... whatever you want
    - freigeben mit commit

    Gegenfrage: was verstehst Du unter "selbstgebautes Locking Verfahren?

    D*B
    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.

  12. #12
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von dschroeder Beitrag anzeigen
    Wir haben alle Tabellen journalisiert. Was heißt denn "Du solltest jedoch Commit=*CHG verwenden" ? Kann ich das im Code angeben oder muss ich dazu Programme mit anderen Optionen kompilieren?
    ... schau dir mal den default von CRTSQLRPGI an (bevor irgendwelche Dilettanten den verändert haben), das ist eine Compile Option.
    Vorsicht: *CHG setzt keine Sperre beim lesen, sondern erst beim schreiben.
    doppelt Vorsicht: SQL setzt bei höherem Sperrlevel beim lesen eine shrnupd Sperre, die dann beim schreiben eskaliert wird (was zu Deadlocks führen kann), bei dem der spätere (!!!) gewinnt.
    dreifach Vorsicht: Sperrelvel serializable setzt eine Sperre auf Dateiebene, was mit Rekord Löffel zu Abbrüchen führt.

    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/

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
  •