-
Guten Morgen Zusammen,
sorry für meine schlechte Erklärung. Es geht noch gar nicht um das Trigger Programm, sondern um das Programm welches prüft, ob STRCMTCTL aktiv ist oder nicht, sprich in dem Programm wird das API QTNRCMTI aufgerufen.
Irgendetwas stimmt nicht, eventuell auch falsch programmiert.
@Birgitta:Vergiss das mit STRCMTCTL. Der Fehler tritt auf, sobald ich das Programm 2x aufrufe, d.h. irgendetwas passiert durch den 1. Aufruf.
Wieso findet das Programm entweder das API nicht mehr oder im API irgendwelche aufgerufenen Programme?
Wo ich mir auch sehr unschlüssig bin ist in der Definition der DS:
Der Wert wird zwar ausgegeben, aber in anderen API's haben wir mit StartPos und Länge auch etwas gemacht.
So sieht es aktuell aus:
h DEBUG ACTGRP(*CALLER) DFTACTGRP(*NO) BNDDIR('*LIBL/SPE')
d ds
d w@lendta 1 4b 0
d w@strpos 5 8b 0
d w@splfx 9 12b 0
d w@rcvle1 13 16b 0
d w@filx 17 22
d w@rcvle 23 26b 0
d w@Rcvva ds
d w@bytrtn 1 4b 0
d w@bytval 5 8b 0
d w@cmtsts 9 9
d w@cmtstsAG 21 21
d w@ErrorDta ds
d w@bytrtne 1 4b 0
d w@bytvale 5 8b 0
d w@ExcepId 9 15
d w@ResChar 16 16
d w@ExcepDta 17 500
c callp RtvCmtData(w@Rcvva:
c w@RcvLe:
c 'CMTI0100':
c w@errorDta)
Die Var w@RCVLE ist mir auch nicht so ganz klar, habe dies aus meinem altem Programm übernommen.
-
Wenn du schon ILERPG nimmst, kannst du auch übersichtliche DS'n erstellen und benötigst keine Byte-Zählerei mehr. Auch die INT-Datentypen sind dann effektiver.
Desweiteren: Wenn Felder nur definiert sind, werden sie nicht automatisch initialisert. Die Error-Struktur muss im 1. Feld die Länge der DS enthalten, die du bereitstellst.
Was den Pointer angeht, so weiß ich halt nicht was das API selber so treibt, aber:
Beim 1. Aufruf eines Programmes werden die Pointer auf Programme intern initialisert.
Wenn du keine Main-Prozedur hast, ist immer der Zyklus aktiv.
D.h., beim Verlassen des Programmes solltest du *INLR = *ON setzen, damit das Programm aus dem Speicher entfernt wird.
Beim nächsten Aufruf wird der Pointer auf ein Programm neu geladen.
Übrigens: DEBUG in den H-Bestimmungen ist nur relevant, wenn du im Programm die DUMP-Anweisung verwenden willst. Ein debugging ist immer möglich.
-
Ich verlasse das Programm mit *INLR, daher sollte alles geschlossen sein.
Die Error DS scheint zu stimmen, das habe ich getestet.
Ich habe die Prozedur durch einen normalen CALL ersetzt, auch hier kommt der Fehler, dass das Objekt nicht mehr gefunden wird.
Man findet auch im Netz kein Beispielprogramm.
Eventuell liegt es auch daran:
Any call to this API will also refresh cached commitment control settings for the current job. The following settings are cached:
- The COMMITMENT_CONTROL_LOCK_LIMIT setting in the QAQQINI query options file to control maximum number of record locks.
- The QIBM_TN_COMMIT_DURABLE environment variable setting to control soft commit.
- The QTN_JRNSAVPT_* environment variable settings to control whether journal entries are sent for savepoint operations.
Wenn ich das Programm neu umwandle, dann funktioniert es nach dem Fehler wieder 1x, also muss irgendetwas auch mit dem Aufruf Stack passieren.
-
Irgendwie bleibt die interne Adresse zum aufrufenden Programm auch nach INLR = *ON erhalten.
Was du probieren kannst, ist der Aufruf per Variable.
Gib bei EXTPGM nicht den Namen sondern eine Variable an.
Wenn eine Variable verwendet wird, wird der Pointer des Programmes erst zur Laufzeit ermittelt.
Vor allem wird durch die Zuweisung der Variablen mit dem Namen der intern generierte Pointer grundsätzlich zurückgesetzt, so dass der CALL das Programm neu ermitteln muss.
Noch ein Tipp:
Verwende in Feldnamen nie @ oder #, da diese nicht CCSID-neutral sind.
Bei Portierung kann das dann schon mal zu Problemen führen.
Nimm lieber "_" wenn du Namen lesbarer gestalten möchtest.
-
Danke, hat leider nicht funktioniert. Auch mit der Variable in EXTPGM kommt der Fehler mit dem nicht gefundenen Objekt.
-
So, wenn ich das Programm unter *NEW kompiliere, dann funktioniert es. Nur so kann ich es nicht gebrauchen.
Ich breche das jetzt ab, würde aber mal die generelle Vorgehensweise in Verbindung mit Trigger und Commit wissen.
Beispiel:
PGM A RPG write in Tabelle A
Trigger wird aufgerufen und schreibt Zusatzdaten in Tabelle B
PGM A bricht ab und muss Daten Tabelle A und B zurückfahren
Das ist mal die Mindestvoraussetzung.
Nun wird es spannend für das Trigger Programm
- Handling bei unterschiedlichen Aktivierungsgruppen *CALLER *NEW
- Handling unter Commit und nicht Commit Umgebung
Wie geht Ihr hier vor?
Danke.
-
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.
-
 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.
hatte ich auch schon überlegt.
-
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 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 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 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!
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