Anmelden

View Full Version : WebService - SQL - SQL-Systemfehler - parallele Verarbeitung?



Seiten : [1] 2

wti
30-03-22, 16:01
Moin zusammen,

ich dachte mir dieser Titel beschreibt das Problem besser - kann aber den vorherigen Thread nicht löschen - sorry...

ich habe ein Problem, bei dem ich mich schwer tue den Ablauf in Worte zu fassen. Trotzdem hoffe ich, dass mir jemand aus der Beschreibung einen Tipp geben kann, der mich in der Analyse bzw. der Problem-Lösung weiterbringt.

Mein SOAP-WebService beinhaltet mehrere Methoden, die Daten für das FrontEnd (.NetCore/C#/WCF-Client) bereitstellen.
Hierfür werden - zum Teil sehr umfangreiche - SQL's (CTE) in einem RPG-Programm (embedded SQL) verwendet. Die Daten werden aus gleichnamigen Tabellen/Dateien in unterschiedlichen Bibliotheken ermittelt.
Um zu vermeiden dass die SQL dynamisch als String aufbereitet werden müssen oder mit unterschiedlichen Bibliotheken dupliziert werden müssen, werden über den Abrechnungszeitraum gesteuert Alias's mit den erforderlichen Bibliotheken in QTEMP erstellt (aktuelle Periode / Vor-Periode / Archiv-Periode). Die Alias's werden zum Ende der Methode wieder gelöscht, da für die nächste Anfrage möglicherweise Daten aus einer anderen Periode ermittelt werden müssen.

Wenn ich das richtig weiß wird für jeden WebService nur ein QZRCSRVS-Job gestartet, was dazu führt dass alle Aufrufe der Methoden des WebService in dem gleichen QZRCSRVS-Job laufen.
Durch die ansteigende Anzahl User kommt es jetzt scheinbar zu Parallel-Verarbeitungen(???)
Meine Vermutung ist nun, dass damit auch alle Methoden-Aufrufe die gleiche QTEMP und damit die gleichen Alias's nutzen, bzw. die Alias's löschen, während ein anderer Methoden-Aufruf diese noch verwendet.

Der Fehler im JobLog zeigt sich wie folgt:

Funktionsfehler X'1720' in Maschineninstruktion. Interne
Speicherauszugs-ID ████████.
*** DBOP open FAILED. Exception from call to SLICÜ ***.
Interner Fehler im Abfrageprozessor.
SQL-Systemfehler.
Cursor CRSNEVGL nicht geöffnet.

Leider lässt sich mit embedded SQL nicht einfach der Tabellen-Name als Variable zuordnen - wie es native möglich ist (dBeaver).

Welche Möglichkeiten habe ich um eine fehlerfreie Parallel-Verarbeitung zu gewährleisten oder muss der Fehler doch anderswo liegen???

Viele Grüße aus dem hohen Norden
Wolfgang

Fuerchau
30-03-22, 16:47
Konzeptioneller Fehler.
Tabellennamen können eben nicht dynmaisch in statischen SQL-Anweisungen verwendete werden.
In Clientanwendungen sind SQL's generell dynamisch. Statische SQL's kennt man da fast gar nicht.
Es gibt da noch ein paar Altsprachen, wo dies ebenso gemacht wurde, in modernen ist das definitiv nicht mehr so.
Du kannst aber relativ einfach aus statischen SQL's eben dynamische SQL's machen.
Je Hostvariable ein "?" und beim Execute eben per Using wieder anfügen.
Dabei kannst du den Tabellennamen halt wechseln.
Alles andere macht hierfür eben keinen Sinn.

Andreas_Prouza
30-03-22, 16:53
Wenn du via JDBC (oder eigentlich egal, da bei HTTP das gleiche ist) auf die IBM i zugreifst, so wird grundsätzlich versucht, den selben Job wiederzuverwenden.
Jetzt kann es vorkommen, dass der gleiche Job von unterschiedlichen Requests verwendet wird.
Du musst in deinem Request jedes mal sicher stellen, dass deine Umgebung (u.a. auch die QTEMP) sauber ist.
Du darfst nicht darauf vertrauen, dass der nächste Request noch mit dem gleichen Job abgearbeitet wird.

BenderD
31-03-22, 07:03
Wenn du via JDBC (oder eigentlich egal, da bei HTTP das gleiche ist) auf die IBM i zugreifst, so wird grundsätzlich versucht, den selben Job wiederzuverwenden.
Jetzt kann es vorkommen, dass der gleiche Job von unterschiedlichen Requests verwendet wird.
Du musst in deinem Request jedes mal sicher stellen, dass deine Umgebung (u.a. auch die QTEMP) sauber ist.
Du darfst nicht darauf vertrauen, dass der nächste Request noch mit dem gleichen Job abgearbeitet wird.

Es ist schon ein wenig anders! Das entscheidende Kriterium ist die Connection. Jede Connection wird von genau einem Serverjob bedient, vom open bis zum close, da gibt es keine Überlappung. Nach dem close steht der Serverjob für die nächste connection bereit. Dabei werden keine offenen Cursor o.ä. vererbt, auf die QTEMP würde ich mich hier nicht verlassen (stellt für mich kein Problem dar, so etwas hat im SQL Umfeld nix verloren!).

D*B

B.Hauser
31-03-22, 07:25
Was mir nicht klar ist, wann werden denn die Aliase in der QTEMP erstellt?
In den embedded SQL Programmen vor dem Aufruf oder einmalig?
Wie stellst Du denn überhaupt fest, welche Umgebung du aktuell hast und welche du brauchst?

Durch die stateless Programmierung ist eben nicht sichergestellt, dass Du in den gleichen Job zurückkommst (auch wenn das vorrangig versucht wird). Ist der Job belegt, wird ein anderer freier Job genommen.

M.E. hast Du eigentlich nur die Chance, jedes Mal zu prüfen welche Umgebung du hast, und falls die nicht passt, musst Du die Aliase neu erstellen und zwar so wie Du sie brauchst.

Anstatt die komplexen SQL Statements direkt im (embedded SQL) Programm zu hinterlegen würde ich die komplexen Select-Statements in Views verpacken und die View für jede Umgebung, in der Du sie brauchst (mit den entsprechenden Bibliotheken anlegen - aktuelle Periode / Vor-Periode / Archiv-Periode) permanent erstellen. Wenn das Ganze auf Views reduziert ist, kannst Du deine Aliase ganz einfach bei Bedarf erstellen ... oder besser dynamisches SQL verwenden, das dann auf die richtige View zugreift.

Birgitta

Fuerchau
31-03-22, 08:46
Die Viewvariante kann für die Dynamik noch ergänzt werden.

Wenn die SQL-Options auf Naming=*SQL stehen, wird ja bei unqualifizierten Zugriffen mit der Default-Collection (Current Schema) zugegriffen.
Somit kannst du folgende Dinge tun:
Je Tabellenvariante eine Lib anlegen, die die komplexe View (oder auch Views auf die Basistabellen) enthält.
Im SQL greifts du ohne Lib auf diese Views zu, so dass Default Collection genommen wird.
Zur Laufzeit kann man per "exec sql set current schema LibName;" den Default ändern, auf den dann der nächste Zugriff entsprechend umgeleitet wird.
Alternativ bei Naming=*SYS, musst du "exec sql set PATH ...;" verwenden um die komplette Library-List zu ersetzen.

BenderD
31-03-22, 08:52
... das zieht beides nicht für Objekte, die man bereits am Wickel hat. Erst mal müsste man überhaupt genauer klären, welches Problem man eigentlich lösen will, bevor man sagen kann, wie es gelöst werden könnte.

D*B

camouflage
01-04-22, 10:42
In dem Zusammenhang hätte ich noch ne Frage.
Kann der Parameter Marker in einem dynamischen SQL auch auf den Dateinamen angewendet werden?

Bis jetzt bin ich noch nicht darauf gekommen, ich beiss mir da die noch restlichen Zähne aus.

p.s. Natürlich kann ich mir das SQL Statement auch ohne die Markers dynamisch zusammenbauen, die Frage zielt explizit auf den Marker.

B.Hauser
01-04-22, 11:35
Kann der Parameter Marker in einem dynamischen SQL auch auf den Dateinamen angewendet werden?


Nein! Das ist quasi statisch, d.h. einmal aufbereitet und mehrfach (mit unterschiedlichen Parameter-Werten) verwendet.
In diesem Fall kann die Datei sowenig über eine Variable gesteuert werden wie beim statischen SQL!

Fuerchau
01-04-22, 15:07
Du kannst aber nach Änderung des Tabellennamens einen neuen Prepare absetzen.
Die Parameterliste des "Execute/Open using" ändert sich da ja nicht.

Nicht vergessen, vor dem Prepare statement noch ein Drop Statement zu verwenden.