-
Generelles zu commit und Transaktionen:
Transaktionen sind immer in einem Kontext zu sehen, d.h., alles was zu einem Kontext gehört muss in einer Transaktion abgeschlossen sein.
Randbedingung: eine Transaktion darf nie durch eine Userinteraktion unterbrochen werden, also z.B. auf eine Bildschirmeingabe warten.
Transaktionen laufen grundsätzlich nur innerhalb einer ACTGRP.
Durch entsprechende Aufrufdefinitionen *CALLER muss also dafür gesorgt werden, dass diese im Kontext in einer ACTGRP passieren.
Wenn man ILERPG/ILECOBOL/CLLE/CLE verwendet, ist ein STRCMTCTL grundsätzlich nicht mehr erforderlich, das erledigt die SQL-Runtime für uns. Dabei wird immer eine Commit-Gruppe der ACTGRP erstellt.
Commit beenden die Transaktion und alle Daten bleiben erhalten. Dies passiert ausschließlich innerhalb der ACTGRP.
Im Job gibt es mehrere Standard-ACTGRP's:
*DEFAULT 1: System-ACTGRP
*DEFAULT 2: User ACTGRP
QILE: 1. automatische ACTGRP für ILE-Programme
"Benannte": durch Programme benannte ACTGRP
*NEW: temporäre ACTGRP
Alle Update/Insert Daten bleiben bei einer aktiven Transaktion gesperrt.
Delete wird ja sofort ausgeführt und ist daher bereits weg.
Bei einem "Select .... for Update" wird beim Lesen beeits gesperrt.
*CHG: Jede Veränderung wird gesperrt.
*CS: Jeder gelesene Satz wird zusätzlich gesperrt
*ALL: Alle gelesenen Sätze werden zusätzlich gesperrt, also Vorsicht!
Ein Commit ist sehr schnell, weil die Commit-Definition geschlossen wird und alle Sperren aufgehoben werden.
Ein Rollback liest nun rückwärts die Daten wieder aus dem Journal und stellt die Daten wieder her.
Danach wird wie beim commit die Commit-Definition geschlossen und alle Sperren aufgehoben.
Ein IDENTITY-Counter wird nie zurückgesetzt.
Zu deiner Frage:
Wenn also alle Programme mit *CALLER erstellt werden, läuft alles in der selben ACTGRP, allerdings mit einer Ausnahme: Jedes Programm muss ILE können!
Wird z.B. ein CLP oder RPGIV aufgerufen, also ein OPM Programm, läuft dieses immer in *DEFAULT 2, hat also eine andere Commit-Ebene.
Hat nun ein Programm oder Service-Programm eine eigene ACTGRP werden hier getrennte Transaktionen durchgeführt. Beim Auflösen der ACTGRP (verlassen der obersten Ebene) wird automatisch ein ROLLBACK gemacht.
Somit kann also ein Service z.B. Protokollsätze schreiben, die auch durch einen Rollback nicht verschwinden. Oder eben eine eigene Transaktion über mehrere Aktionen erstellen.
Trigger:
Es ist per Definition nicht erlaubt, dass ein Trigger eine Transaktion abschließt.
Dies gilt auch für aus dem Trigger aufgerufenen Programme innerhalb derselben Transaktion.
Wenn ein Trigger eine andere ACTGRP aufruft, kann diese wiederum eigene Transaktionen durchführen.
Achtung vor Rekursion:
Standard ILERPG ist nicht rekursionsfähig. Um eine Rekursion zu ermöglichen, muss das Programm über eine MAIN-Funktion verfügen und hat dann keinen Zyklus.
Eine endlose Rekursion gibt es nicht, da stirbt dann die ACTGRP.
Deadlocks:
Durch die ACTGRP's kann es auch innerhalb eines Jobs bereits zu Deadlocks kommen, also nicht nur jobübergreifend.
So, für einen groben Überblick sollte das reichen.
-
 Zitat von B.Hauser
Vielleicht sieh ich das mal wieder zu einfach!
Ich würde einfach den CL-Befehl STMCMTCL ausführen. Wenn er klappt, war Commitment Steuerung nicht aktiv, dann beende ich die Commitemnt Control wieder.
Ist die Commitment Control aktiv, geht STMCMTCL schief.
So habe ich es jetzt auch gemacht.
Aber es bleibt noch eine Unschärfe, die mich interessiert, wie das so in der Praxis umgesetzt wird.
STRCMTL ist gemacht
PGM A hat mehrere Dateien unter Commit, aber nicht die Datei, wo der Trigger hängt
durch eine Dateioperation wird der Trigger ausgelöst
Das Trigger Programm würde vermutlich abbrechen, weil der STRCMTL aktiv ist, aber nicht die Datei des Triggers unter commit läuft
Prinzipiell könnte man dies auch als Programmfehler abstempeln, aber ausschließen kann ich es halt auch nicht.
Man müsste erkennen, ob die Datei in dem Trigger Programm unter Commit läuft. Den API's vertraue ich da nicht wirklich.
-
 Zitat von Fuerchau
Generelles zu commit und Transaktionen:
Transaktionen sind immer in einem Kontext zu sehen, d.h., alles was zu einem Kontext gehört muss in einer Transaktion abgeschlossen sein.
Randbedingung: eine Transaktion darf nie durch eine Userinteraktion unterbrochen werden, also z.B. auf eine Bildschirmeingabe warten.
Transaktionen laufen grundsätzlich nur innerhalb einer ACTGRP.
Durch entsprechende Aufrufdefinitionen *CALLER muss also dafür gesorgt werden, dass diese im Kontext in einer ACTGRP passieren.
Wenn man ILERPG/ILECOBOL/CLLE/CLE verwendet, ist ein STRCMTCTL grundsätzlich nicht mehr erforderlich, das erledigt die SQL-Runtime für uns. Dabei wird immer eine Commit-Gruppe der ACTGRP erstellt.
Commit beenden die Transaktion und alle Daten bleiben erhalten. Dies passiert ausschließlich innerhalb der ACTGRP.
Im Job gibt es mehrere Standard-ACTGRP's:
*DEFAULT 1: System-ACTGRP
*DEFAULT 2: User ACTGRP
QILE: 1. automatische ACTGRP für ILE-Programme
"Benannte": durch Programme benannte ACTGRP
*NEW: temporäre ACTGRP
Alle Update/Insert Daten bleiben bei einer aktiven Transaktion gesperrt.
Delete wird ja sofort ausgeführt und ist daher bereits weg.
Bei einem "Select .... for Update" wird beim Lesen beeits gesperrt.
*CHG: Jede Veränderung wird gesperrt.
*CS: Jeder gelesene Satz wird zusätzlich gesperrt
*ALL: Alle gelesenen Sätze werden zusätzlich gesperrt, also Vorsicht!
Ein Commit ist sehr schnell, weil die Commit-Definition geschlossen wird und alle Sperren aufgehoben werden.
Ein Rollback liest nun rückwärts die Daten wieder aus dem Journal und stellt die Daten wieder her.
Danach wird wie beim commit die Commit-Definition geschlossen und alle Sperren aufgehoben.
Ein IDENTITY-Counter wird nie zurückgesetzt.
Zu deiner Frage:
Wenn also alle Programme mit *CALLER erstellt werden, läuft alles in der selben ACTGRP, allerdings mit einer Ausnahme: Jedes Programm muss ILE können!
Wird z.B. ein CLP oder RPGIV aufgerufen, also ein OPM Programm, läuft dieses immer in *DEFAULT 2, hat also eine andere Commit-Ebene.
Hat nun ein Programm oder Service-Programm eine eigene ACTGRP werden hier getrennte Transaktionen durchgeführt. Beim Auflösen der ACTGRP (verlassen der obersten Ebene) wird automatisch ein ROLLBACK gemacht.
Somit kann also ein Service z.B. Protokollsätze schreiben, die auch durch einen Rollback nicht verschwinden. Oder eben eine eigene Transaktion über mehrere Aktionen erstellen.
Trigger:
Es ist per Definition nicht erlaubt, dass ein Trigger eine Transaktion abschließt.
Dies gilt auch für aus dem Trigger aufgerufenen Programme innerhalb derselben Transaktion.
Wenn ein Trigger eine andere ACTGRP aufruft, kann diese wiederum eigene Transaktionen durchführen.
Achtung vor Rekursion:
Standard ILERPG ist nicht rekursionsfähig. Um eine Rekursion zu ermöglichen, muss das Programm über eine MAIN-Funktion verfügen und hat dann keinen Zyklus.
Eine endlose Rekursion gibt es nicht, da stirbt dann die ACTGRP.
Deadlocks:
Durch die ACTGRP's kann es auch innerhalb eines Jobs bereits zu Deadlocks kommen, also nicht nur jobübergreifend.
So, für einen groben Überblick sollte das reichen.
Danke Dir für die ausführliche Beschreibung.
-
 Zitat von itec01
So habe ich es jetzt auch gemacht.
Aber es bleibt noch eine Unschärfe, die mich interessiert, wie das so in der Praxis umgesetzt wird.
STRCMTL ist gemacht
PGM A hat mehrere Dateien unter Commit, aber nicht die Datei, wo der Trigger hängt
durch eine Dateioperation wird der Trigger ausgelöst
Das Trigger Programm würde vermutlich abbrechen, weil der STRCMTL aktiv ist, aber nicht die Datei des Triggers unter commit läuft
Prinzipiell könnte man dies auch als Programmfehler abstempeln, aber ausschließen kann ich es halt auch nicht.
Man müsste erkennen, ob die Datei in dem Trigger Programm unter Commit läuft. Den API's vertraue ich da nicht wirklich.
... wer hat denn diesen Verhau angerichtet? Jetzt wundert es mich auch nicht mehr, dass weder der Trigger Buffer, noch QTNRCMTI die passende Information liefert. Dasselbe Programm läuft mal unter commit, mal nicht und wenn es unter commit läuft, dann wird eine Datei mal mit, mal ohne commit geöffnet und dann hänge ich noch einen Trigger an diese Datei, der damit zurecht kommen soll.
Warum nehmt ihr das Feld für den User nicht einfach in die Datei auf und lasst es von der Datenbank pflegen?
D*B
PS: Sauberer wäre es allerdings diesen Huddel zu bereinigen!
-
Ja und dann auch nicht die Fälle vergessen, bei denen am SQL noch ein "with nc" hängt.
Z.B. "insert into table bla values(.....) with nc".
-
 Zitat von BenderD
... wer hat denn diesen Verhau angerichtet? Jetzt wundert es mich auch nicht mehr, dass weder der Trigger Buffer, noch QTNRCMTI die passende Information liefert. Dasselbe Programm läuft mal unter commit, mal nicht und wenn es unter commit läuft, dann wird eine Datei mal mit, mal ohne commit geöffnet und dann hänge ich noch einen Trigger an diese Datei, der damit zurecht kommen soll.
Warum nehmt ihr das Feld für den User nicht einfach in die Datei auf und lasst es von der Datenbank pflegen?
D*B
PS: Sauberer wäre es allerdings diesen Huddel zu bereinigen!
Genau das haben wir ja, ein User Feld in der DB, die durch den Trigger gefüllt wird. Hatte ich ganz am Anfang geschrieben.
Ich hatte mein Beispiel zuvor ja als Fehler abgestempelt (wir haben das so nicht programmiert), aber dennoch wollte ich nur wissen, ob man im RPG erkennt, ob eine Datei gerade unter commit läuft.
Aber auf jeden Fall ist mit den Triggern unter commit nicht zu spaßen, ganz besonders wenn mal so (SQL commit) oder so (RPG commit) gemacht wurde.
-
Ob per SQL oder per RPG gibts tatsächlich einen Unterschied.
Wenn STRCMTCTL nicht gestartet ist, gibts beim RPG-Commit eine Abbruchmeldung.
Beim exec sql commit gibts nur einen SQLSTATE bzw. SQLCODE.
Wenn man einen Before-Update/Insert Trigger macht, braucht man ja nur den Datenpuffer zu ändern und sich um Commit nicht kümmern, was per Definition ja sowieso nicht erlaubt ist.
-
 Zitat von itec01
Genau das haben wir ja, ein User Feld in der DB, die durch den Trigger gefüllt wird. Hatte ich ganz am Anfang geschrieben.
Ich hatte mein Beispiel zuvor ja als Fehler abgestempelt (wir haben das so nicht programmiert), aber dennoch wollte ich nur wissen, ob man im RPG erkennt, ob eine Datei gerade unter commit läuft.
Aber auf jeden Fall ist mit den Triggern unter commit nicht zu spaßen, ganz besonders wenn mal so (SQL commit) oder so (RPG commit) gemacht wurde.
... für ein Feld in der selben Datei reicht es aus with default(user) bei der Erstellung anzugeben und das Feld in Ruhe zu lassen, dann steht der Inhalt des special register USER beim insert und update drin und beim ROLLBACK wird das zurückgesetzt auf den vorherigen Wert. Da braucht es keine Dateioperation im Trigger, die ACTGRP ist dann Wurscht und das Sperrlevel des Triggers ist ebenfalls egal.
D*B
-
 Zitat von BenderD
... für ein Feld in der selben Datei reicht es aus with default(user) bei der Erstellung anzugeben und das Feld in Ruhe zu lassen, dann steht der Inhalt des special register USER beim insert und update drin und beim ROLLBACK wird das zurückgesetzt auf den vorherigen Wert. Da braucht es keine Dateioperation im Trigger, die ACTGRP ist dann Wurscht und das Sperrlevel des Triggers ist ebenfalls egal.
D*B
Danke Dir, ja ich weiß, aber funktioniert bei uns nicht, weil im Falle von Barcode Prozessen mit Handscannern ein 4stelliger User stehen muss. Daher die Idee mit dem Trigger.
-
Das ist ja auch legitim, aber wofür muss der Trigger wissen, ob Commit an oder aus ist?
-
 Zitat von Fuerchau
Das ist ja auch legitim, aber wofür muss der Trigger wissen, ob Commit an oder aus ist?
Ich hatte es doch versucht zu erklären. Wenn das Trigger Programm es nicht weiß, dann bricht es mir ab, je nachdem ob der STRCMTL aktiv ist oder nicht. Ich möchte auf keinen Fall mit dem trigger Programm etwas festschreiben, was im Falles eines mögliches Rollbacks dann stehen bleibt.
Das Trigger Programm hat in den F-Bestimmungen den commit unter Bezugszahl. Die Bezugszahl setze ich aktuell auf 1 oder 0, je nachdem ob der STRCMTL aktiv ist oder nicht.
-
Da hilft dann nichts anderes, als den Open in eine Monitor-Gruppe zu stellen und den Open mit Commit zuerst zu versuchen.
Genauso musst du die Dateien aber auch sofort wieder schließen, da beim nächsten Mal der Status ein anderer sein kann.
Performant wird das sicher nicht, da Dateien im Trigger ja durchaus offen bleiben könnten.
Aber noch mal auf Anfang zurück:
"und im Trigger Programm einen chain und update gemacht."
Warum machst du keinen Before-Trigger, hatte ich oben schon mal gefragt?
Dann ergänzt du die Daten nur im Datenpuffer "Before-Image" und der Write erfolgt dann nach dem Trigger.
Beim ADDPFTRG muss dann ALWREPCHG(*YES) gesetzt werden um Pufferänderungen zu erlauben.
Similar Threads
-
By schatte in forum NEWSboard Programmierung
Antworten: 1
Letzter Beitrag: 22-03-19, 16:52
-
By rr2001 in forum IBM i Hauptforum
Antworten: 10
Letzter Beitrag: 03-09-15, 07:37
-
By KingofKning in forum IBM i Hauptforum
Antworten: 14
Letzter Beitrag: 10-03-15, 14:29
-
By Mädele in forum IBM i Hauptforum
Antworten: 1
Letzter Beitrag: 26-12-05, 09:43
-
By Wirnitzer in forum IBM i Hauptforum
Antworten: 4
Letzter Beitrag: 17-10-01, 10:13
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks