PDA

View Full Version : RPGLE an einer Transaktion teilnehmen lassen?



Bratmaxxe
23-02-11, 09:25
Hallo,

ich stehe vor folgendem Problem:

Ein EJB Service erstellt einen Datensatz. Wenn ein Feld dieses Datensatzes eine bestimmte Information enthält, soll zusätzlich eine StoredProcedure aufgerufen werden, die den Datensatz noch mit weiteren Informationen anreichert, die der EJB Service auch gar nicht kennen soll.

Jetzt ist es so, dass wenn die StoredProcedure aufgerufen wird diese im MSGW stehen bleibt, da der Datensatz gesperrt ist (EJB Transaktion ist noch nicht abgeschlossen).

Daher meine Frage, ist es überhaupt möglich die Procedure an der Transaktion des EJB Services teilhaben zu lassen ?

Gruß
Bratmaxxe

Fuerchau
23-02-11, 09:29
Wenn der datensatz noch gesperrt ist, hast du keine Chance das über ein Programm zu machen.

Besser ist hier ein Before-Insert-/Before-Update-Trigger, der kann dann das Satz-Abbild vor dem Insert ergänzen.

Dem Trigger mauss allerdings das Ändern auch erlaubt sein.

Bratmaxxe
23-02-11, 10:56
Hallo Herr Fuerchau,

danke für Ihre Antwort.

In diesem Forum bin ich auf folgendes gestoßen:

jGuru: Calling RPG as part of a java/jdbc transaction (http://www.jguru.com/forums/view.jsp?EID=416680)

allerdings klappt's nicht - E/A Fehler weil der Datensatz gesperrt ist...

Kann man hier mit STRCMTCTL nicht noch was schrauben ?

Gruß
Bratmaxxe

Fuerchau
23-02-11, 12:37
Nein.
Entweder über Insert-Trigger oder vor dem Aufruf der Procedure die Daten committen!
Dann wird die Sperre aufgehoben.

mng
23-02-11, 12:59
Um die ursprüngliche Frage noch mal aufzuwärmen:
Es ist also nicht möglich, dass das RPG / StoredProcedure an der Transaktion des EJB's (EJB Containers) teilnimmt?
Gäbe es das Problem des gesperrten Satzes, wenn die StoredProcedure dazu in der Lage wäre?

Fuerchau
23-02-11, 13:08
Es kann nur dann an der Transaktion teilnehmen, wenn andere Daten verarbeitet werden.
Gesperrte Sätze können nür dann verarbeitet werden, wenn das Programm in der selben ACTGRP läuft.
D.h., für RPG (OPM) ist das ausgeschlossen.

Für ILERPG mit ACTGRP(*CALLER) müsste es eigentlich funktionieren.

Besser wäre allerdings
- Trigger (wie gesagt)
- die Prozedur schreibt die Daten insgesamt selber weg

Bratmaxxe
23-02-11, 13:36
Hallo Baldur,

heißt andere Daten = andere Tabellen oder wie ist das gemeint ?

Angenommen, mein Service schreibt in eine Datei (HUGO), dann dürfte das RPG-Programm kein Update auf HUGO machen, aber zwar Datei GUSTAV und BERTA per Update/Write/Delete verarbeiten.

Anbei noch meine StoredProcedure Definition:




H DECEDIT('0,') DATEDIT(*DMY.)
H DFTACTGRP(*NO) ACTGRP(*CALLER)

CREATE PROCEDURE PGM/MYPGM(IN PUSER CHAR (10 ), IN PMANDBED CHAR
(3 ), IN PMANEF CHAR (3 ), IN PBEDARFNR DEC (10 ), IN PFKST DEC (4
), IN PBEMERK CHAR (80 )) LANGUAGE RPGLE NOT DETERMINISTIC NO SQL
EXTERNAL NAME PGM/MYPGM PARAMETER STYLE GENERAL

CRTSQLRPGI OBJ(PGM/MYPGM) SRCFILE(PGMSRC/QRPGLESRC) COMMIT(
*NONE)
OUTPUT(*PRINT) OPTION(*XREF *SEQSRC) CLOSQLCSR(*ENDMOD) DBGVIEW(
*SOURCE)



Gruß
Bratmaxxe

Fuerchau
23-02-11, 18:29
Der Fehler liegt in der Prozedure-Deklaration:

NO SQL

erlaubt keine Dateioperationen!
CONTAINS SQL wäre da schon besser.

Dann klappts eigentlich auch mit Transaktionen.

Wichtig ist aber, dass dein Programm keine OPTION COMMIT=*NONE enthält sonst wirds hier auch schwierig.

Alle Dateien, die du in deinem Programm verwendest sollten/müssen journalisiert sein, da sonst ein Rollback unmöglich ist.

Bratmaxxe
24-02-11, 07:58
Hallo Baldur,

habe alles gemäß Posting berücksichtigt - funktioniert leider immer noch nicht...

Als ich jedoch in den F-Bestimmungen für die Datei das Schlüsselwort "COMMIT" angegeben habe, funktionierte es tatsächlich !

Der EJB Service läuft, jedoch melden andere RPG Programme die die StoredProcedure aufrufen "Fehlernachricht CPF4326 wurde während OPEN für Datei XYZ - tatsächliche Datei ist XYZ"...

Wie komm ich aus dieser misslichen Lage wieder raus ?

Gruß
Bratmaxxe

Fuerchau
24-02-11, 08:37
Wenn eine Datei unter Commit-Steuerung bearbeitet werden soll, so muss vorher ein STRCMTCTL abgesetzt werden.
SQL macht dies für dich automatisch.

Dein Problem ist dann jedoch, dass deine anderen Programme nach Aufruf der Prozedur auch einen Commit absetzen müssen, damit die Änderungen festgeschrieben werden, sonst läuft alles bis zum Jobende unter einer Transaktion für die dann ein Rollback abgesetzt wird.

Insgesamt stellt sich also die Mischung aus Aufruf aus SQL (ODBC) und Aufruf aus anderen Programmen als problematisch dar.

Eine Lösung kann ich dir da so direkt nicht anbieten.

Auch wenn du dein Prozedur auf rein SQL umstellst, hast du immer noch das Problem, dass OPTION COMMIT=*NONE nicht erlaubt ist und beim Aufruf ohne vorherigen STRCMTCTL deine Prozedur mit Fehler auf die Datei zugreift.

Die einzige Möglichkeit hier ist wohl, zwei Versionen zu stricken.

a) Prozedur zum Aufruf aus SQL
b) Programm zum Aufruf aus anderen Quellen

Besser wäre aber immer noch ein Trigger, denn da wäre es dann egal da du nur Puffer veränderst.