PDA

View Full Version : DTAQs vs. Stored Procedures



us400
19-01-06, 14:15
Hallo Experten,

ich muss mit einer .NET-Anwendung mit RPG-Programmen kommunizieren. Dazu wollte ich eigtl. auf die Toolbox für Java zurückgreifen. Konkret habe ich mir folgende (wohl recht kompliziert erscheinende) Lösung ausgedacht.

Auf der iSeries bilde ich eine Java-Schicht zwischen den RPG-Programmen und der externen .NET-Anwendung. Diese wird in Form von WebServices in Verbindung mit Tomcat realisiert. Die externe .NET-Anwendung stellt Requests an diese Java-Webservices. Die WebServices unterhalten sich dann mit den RPG-Programmen via DataQueues, so etwa nach dem Motto ein RPG-Programm lauscht auf einer Queue und wartet auf Requests von den WebServices, die es bei Eintreffen entsprechend bedient. Die WebServices wiederum bedienen die Requests der externen .NET-Anwendung.

Das hört sich allerdings sehr aufwendig an, nicht zuletzt weil drei verschiedene Entwicklungsumgebungen eingesetzt würden.

Nun habe ich in diesem Forum von StoredProcedures und SQL als Alternative zu DATQs und Toolbox gelesen. Geht das auch direkt in Verbindung mit .NET, also Stored Procedures auf RPG-Basis, die von .NET via ADO.NET aufgerufen werden und so ne Art ResultSet/DataSet zurückliefern?

Bin für jeden Hinweis dankbar, der mein komplexes Design vereinfacht!

KM
19-01-06, 17:29
Ich kenne mich jetzt überhaupt nicht mit .NET aus. Aber wenn Du von Deinem System aus eine ODBC-Verbindung zur iSeries erstellen kannst, dann kannst Du ohne Probleme per SQL-CALL eine Stored Procedure auf der iSeries aufrufen. Dazu kannst Du ein ganz normales RPG-Programm nehmen und dieses als Stored Procedure registrieren. Das RPG-Programm kann Ein- bzw. Ausgabeparameter haben oder auch einen ResultSet zurückliefern.
Ich habe so etwas gerade von PHP-Seite aus realisiert.

Gruß,
KM

Fuerchau
19-01-06, 19:08
Als Alternative kann man StoredProcedures auch direkt in SQL entwickeln.
Ab V5Rx ist auch kein eigener Compiler auf der AS/400 mehr erforderlich.
Mit dem Testen wirds allerdings etwas schwieriger.

RobertPic
19-01-06, 20:58
WebServices verwendet man normalerweise nur, wenn die Client's von irgendwo über das WWW ihre Verbindung aufbauen müssen. Ein Umweg denn ich für den Einsatz im Intranet auf jeden Fall vermeiden würde.

Man kann auch SQL StoredProcedures und RPG-Programme kombinieren und z.B. eine ganze Datei an das .NET zurückzugeben.

Beispiel:

Aufgrund von Parameter1 soll das RPG-Programm (ALTESRPG) die Ausgabedatei QTEMP/OUTPUT erstellen.



CREATE PROCEDURE LIB/ALTESPGM (IN PARAM1 CHAR(10))
LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN
DECLARE c1 CURSOR WITH RETURN FOR
SELECT *
FROM QTEMP/OUTPUT;

CALL LIB/ALTESRPG (PARAM1);
OPEN c1;
END



statt einem SELECT verwendet man CALL in der DB-Verbindung:

cm_SQL.CommandText = "{CALL LIB.ALTESPGM(?)}"
..
Wie bei einem Select erhält man ein auch in diesem Fall ein RecordSet mit den Sätzen der ALTESRPG-Ausgabe.

Das ist nicht nur weniger Aufwand, wie der Umweg WebServices, sondern auch wesentlich performanter.

Robert P.

us400
20-01-06, 08:24
Wow, das war mein erster Forums-Beitrag. Bin begeistert von euren schnellen Reaktionen (muss wohl an der Einfachheit des Problems liegen :-) Das ist genau das was ich gesucht habe: Direkt von .NET auf eine RPG-Schicht (in Form einer eines SQL-Calls auf eine Stored Procedure) zugreifen, wodurch die Daten gekapselt bleiben.

Vielen Dank an alle "Antworter"!

Wie performant sind denn solche Aufrufe von Stored Procedures? Ist das vergleichbar mit direkten Programmaufrufen auf Systemebene, oder geht das etwas schneller (weil schon in den Hauptspeicher geladen oder so etwas)?

Fuerchau
20-01-06, 09:43
Die Perfomance ist nur bedingt vergleichbar.
Je nach Funktion, die benötigt wird, ergeben sich halt Unterschiede.
Die schnellste Variante ist sicherlich das Zurückgeben ganzer Recordsets. Dabei ist der Aufruf selbst absolut zu vernachlässigen.
Wird mit einer Prozedur nur wenig gemacht, ist der Aufruf zwar relevant, aber in den meisten Fällen nicht wirklich messbar.

Hintergrund:
Wenn ich per CLP einen CALL mache, muss erst das Objekt ermittelt werden bevor der Aufruf erfolgt.
Wenn ich per HLL-Programm (RPG/COBOL) einen CALL 'Konstante' durchführe, ermittelt das System beim Programmstart die Adresse des Objektes, so dass der nachfolgende CALL dann etwa wie ein GOTO wirkt.
Ein Aufruf CALL VARIABLE ist wiederum nur beim 1. Mal langsam (Objektsuche), bei Wiederholungen wieder wie GOTO zu verstehen.

Was den wesentlichen Zeitfaktor beim CALL angeht, so sind das die Resourcen, die bereits beim 1. Aufruf benötigt werden.
Bei ILE-/RPG alle Dateien, die automatisch geöffnet werden sowie alle CALL 'KONSTANTE', und zwar unabhängig davon, ob sie im Laufe des Programmes auch tatsächlich benötigt werden.
Deshalb ist es manchmal sinnvoll, Dateien mit USROPN zu öffnen und Programme per Variable aufzurufen (allerdings fehlen diese dann bei DSPPGMREF).
Bei RPG kommt dann noch die *INLR-Abhängigkeit hinzu, ob wiederholte Aufrufe beim nächsten mal schneller sind.
In COBOL werden Dateien immer per USROPN gesteuert, einzig die CALL's werden initialisiert.
Bei CLP's und C-Programmen gibt es keine Resourcen, ie beim CALL initialisiert werden müssen.

Der Aufruf von Serviceprogrammen soll mitunter der schnellste sein.

Aber: Diese ganze Diskussion ist fast nicht relevant.
Ich habe bereits mehrere 1000 Call's pro Sekunde in einem Batchjob gesehen, bei gleichzeitig ca. 1500 weiteren parallelen Job's.

Viel Problematischer sind da eher falsche SQL's (Zugriffspfade, Tablescan's) sowie das Netzwerk bei Remote-Zugriffen.
Was bringt mir da eine Optimierung der CALL's um Microsekunden, wenn der Netztransfer Sekunden oder der SQL Minuten benötigt.

BenderD
21-01-06, 09:46
Hallo,

das ist der Kern der ganzen Debatte!
First do it right, then make it fast. Den ersten Entwurf sauber strukturieren, jede Teilfunktionalität zentralisieren und ohne große Rücksicht auf Performance implementieren. Dann die Stellen ermitteln (durch messen!!! Log4J ist dein Freund), wo die Zeit verbraucht wird und diese optimieren (wieder messen!!!). Für den Serverteil kann man bei stored Procedures den Database Monitor verwenden.
Beim Vergleich der beiden Varianten (stored Procedures und DTAQ) ist noch zu breücksichtigen:
- JDBC ist deutlich ausgereifter als das Toolbox Spielzeug (DTAQs)
- JDBC Connections kann man einfach poolen
- ein zentraler DTAQ Server Job ist ein Flasschenhals, da RPG nicht Multithreading kann
- multiple DTAQ Server sind (fast) immer wackeliger als die QZDASOINIT Jobs
Zu Baldurs Argumenten würde ich noch ergänzen:
- Wartezeiten auf Ressourcen und Ressourcen Engpässe sind der primäre Flaschenhals
- Lock Konflikte gehören zu den beliebtesten Fehlern, mit beliebigen Wartezeiten und/oder Fehlfunktionen
- bei eigenen Serverjobs ist das warten auf abgeschmierte Server auch sehr beliebt.
- bei der Java RPG Variante sind die synchronen Übergänge zwischen RPG und Java am übelsten; also:
- Aufruf von Java aus RPG mit Start einer JVM pro Job
- Aufruf von RPG aus Java mittels JNI
Mein Resumee:
- am besten wäre das komplett in Java zu machen.
- das beste vom zweitbesten sind stored Procedures
- DTAQs trotten mit Abstand dahinter
- mit RPG Java Mix fliegt man entweder sofort raus, oder hat eine Lebensstellung.

mfg

Dieter Bender

PS: Zu dieser Problematik gibt es auch ein paar Hinweise in meiner Java auf AS400 FAQ auf meiner Webseite.





Aber: Diese ganze Diskussion ist fast nicht relevant.
Ich habe bereits mehrere 1000 Call's pro Sekunde in einem Batchjob gesehen, bei gleichzeitig ca. 1500 weiteren parallelen Job's.

Viel Problematischer sind da eher falsche SQL's (Zugriffspfade, Tablescan's) sowie das Netzwerk bei Remote-Zugriffen.
Was bringt mir da eine Optimierung der CALL's um Microsekunden, wenn der Netztransfer Sekunden oder der SQL Minuten benötigt.