Anmelden

View Full Version : Wie bekomme ich Record-Locking mit embedded SQL hin?



Seiten : [1] 2 3

dschroeder
01-12-23, 09:28
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

manuel.marcos
01-12-23, 11:13
Hallo,
sollte es nicht reichen wenn du den Datensatz mit for update liest? Und mit Update gibst du dann wieder frei.

Gruß,
Manuel

Andreas_Prouza
01-12-23, 11:32
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.

dschroeder
01-12-23, 11:55
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.

dschroeder
01-12-23, 11:56
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?

Andreas_Prouza
01-12-23, 12:21
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.

dschroeder
01-12-23, 12:29
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:


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?

Fuerchau
01-12-23, 12:42
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.

BenderD
01-12-23, 12:55
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

dschroeder
01-12-23, 14:08
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?