View Full Version : Emb. SQL und geöffnete Dateien
Hallo zusammen,
wieder einmal habe ich ein Problem das mir nicht ganz einleuchtet. Ich hoffe jemand von euch kann mir dabei weiter helfen.
In einem Serviceprogramm habe ich eine Prozedur um div. Kundendaten per SQL auszulesen. Das funktioniert auch perfekt, allerdings bleiben die im Statement verknüpften Dateien offen, wenn ich die Prozedur in einem Programm verwende in dem Datensätze zu mehreren Kunden hintereinander verarbeitet werden, obwohl der Cursor immer wieder geschlossen wird.
Wieso bleiben die Dateien offen?
Danke!
Joe
Wieso bleiben die Dateien offen?
Weil SQL so arbeitet!!!
Der Close im Programm ist lediglich ein Soft- oder Pseudo-Close, d.h. er bewirkt nur, dass beim nächsten Aufruf die Daten im geöffneten Datenpfand aktualisiert werden können und dass der Cursor an den Anfang repositioniert wird.
Da der Optimierungsaufwand bei SQL weit höher ist als bei native I/O, d.h. ein Access Plan muss erstellt oder zumindest validiert werden (die vorhandenen Zugriffswege müssen bewertet werden und es muss festgelegt werden, welche temporären Objekte z.B. Hast Tables benötigt werden. Nach dieser Phase wird der Datenpfad (ODP) gebildet/geöffnet, d.h. die temporären Objekte erstellt und mit Daten gefüllt.
Wenn der ODP wieder verwendbar ist, bleibt er geöffnet, bis er über einen HARD Close geschlossen wird. Beim Hard Close werden die temporären Objekte gelöscht und beim nächsten Aufruf muss die komplette Optimierungs-/Öffnungs-Orgie wieder durchlaufen werden (FULL-OPEN).
Beim PSEUDO-Open, werden jeweils nur die Daten in den temporären Objekten aktualisiert.
Wenn Du Dein Programm mit Unterlassungswerten umgewandelt hast (wovon ich ausgehe) bleibt der ODP geöffnet, bis die Aktivierungsgruppe, in der das Programm oder die Prozedur läuft geschlossen wird.
Der ODP wird gelöscht, wenn Du in der Compile-Option CLOSQLCSR im Befehl CRTRPGSQLI *ENDMOD angibst. Dann wird der ODP jeweils beim Modul-Ende gelöscht. Bei wiederholten Aufrufen und vielen SQL-Statements kann dies zu einer wesentlich schlechteren Performance führen. Deshalb sollte diese Option nur in Ausnahmefällen geändert werden.
Birgitta
ja, ja der open close. Richtig ist erstmal, dass SQL möglichst lazy closes macht (sprich es setzt einen Merker, dass das Programm close gesagt hat, wenn dann der open kommt, sagt sich SQL, das habe ich mir doch gleich gedacht, positioniert den Cursor neu und macht den Merker weg. Das ist von Vorteil, solange die Query Engine keinen Schuss hat: sprich: die Zuordnung korrekt findet und nicht den einen nur logisch schließt und einen neuen aufmacht! (in diesem Fall hilft dann ein PTF).
Beeinflussen kann man das eigentlich nur durch einen disconnect von der Datenbank mit folgendem neuem Connect, der sollte die Ressourcen wirklich freigeben, aber selbst da bin ich mir bei neueren Releases (sprich SQE) nicht immer sicher.
Die Einstellungen von CLOSQLCSR wirken nach meiner Erfahrung (die auch von der Doku gestützt wird (IBM Software Technical Document 6492409 Herr Google hilft beim suchen) nicht auf die ODPs, sondern machen im Grunde dasselbe, wie ein close im SQL, bei korrektem Design der Anwendung ist das ohne jede Auswirkung, da dann die erforderlichen open close Anweisungen aus dem Programm kommen und das Transaktions steuernde Programm das in der Hand hat - nach ANSI Standard ohne DB2 Erweiterungen impliziert das Transaktions Ende (Commit/Rollback) das schließen der Cursor und die Freigabe der Ressourcen.
Am Rande sei hier noch vermerkt, dass Objektsperren durch ODPs, deren Cursor im Status closed sind beim ALCOBJ über den Parameter RQSRLS geholt werden können, was SQL beim Sperren anfordern immer automatisch macht.
Was den Einfluss auf die Performace angeht:
- in der Summe wird durch die lazy close Startegie von SQL Zeit eingespart
- wenn ein full open mehr als centi (1/100) Sekunden benötigt, fehlt meist ein Index
- in wenigen Fällen kann ein vorhandener ODP von Übel sein, weil eine ältere Zugriffs Strategie beibehalten wird, obwohl mittlerweile eine andere besser wäre
Empfehlung: diesen Parameter auf default Einstellung belassen, wenn man mit Commit Scope *ACTGRP arbeitet und wenn man mit Commit Scope *JOB arbeitet auf diese Ebene anpassen.
D*B
D*B
Wenn Du Dein Programm mit Unterlassungswerten umgewandelt hast (wovon ich ausgehe) bleibt der ODP geöffnet, bis die Aktivierungsgruppe, in der das Programm oder die Prozedur läuft geschlossen wird.
Der ODP wird gelöscht, wenn Du in der Compile-Option CLOSQLCSR im Befehl CRTRPGSQLI *ENDMOD angibst. Dann wird der ODP jeweils beim Modul-Ende gelöscht. Bei wiederholten Aufrufen und vielen SQL-Statements kann dies zu einer wesentlich schlechteren Performance führen. Deshalb sollte diese Option nur in Ausnahmefällen geändert werden.
Birgitta
(die auch von der Doku gestützt wird (IBM Software Technical Document 6492409 Herr Google hilft beim suchen) nicht auf die ODPs,
Ist Dir auch aufgefallen, dass in dem Dokument 6492409 nur von RPGIII geredet wurde und nicht RPGIV oder ILERPG.
Die Optionen *ENDPGM, *ENDJOB und *ENDSQL können nur bei CRTSQLRPG (sprich RPGIII) und nicht bei CRTSQLRPGI (sprich RPGIV) angegeben werden. Bei CRTSQLRPGI heißen die Optionen *ENDMOD und *ENDACTGRP.
In ILE funktioniert die Option *ENDMOD wie *ENDPGM, während bei der Option *ENDACTGRP der ODP geöffnet bleibt und wiederverwendbar ist, solange die Aktivierungsgruppe nicht beendet wird.
Aus dem Dokument 6492409:
A RPG program is created with *ENDPGM. It issues a declare, open, and fetch of a cursor, then the program ends. Because the program ends, the cursor and the ODP are discarded.
Damit wird auch beim *ENDMOD der ODP gelöscht (discarded = weggeworfen).
Dokumentationen über CLOSQLCSR findet man in der Online Library in Database Performance and Query Optiomization:
General rules for retaining cursor positions for all program calls (http://publib.boulder.ibm.com/infocenter/systems/scope/i5os/index.jsp?topic=/rzajq/retrs.htm&tocNode=int_98251)
Birgitta
ja, das ist mir aufgefallen, nur die von dir angegebene Fundstelle hilft da nicht weiter, die bezieht sich auf den Erhalt der Cursor Position und stellt dem wiederholte open/close gegenüber (die den Cursor jedesmal neu positionieren.
Nett, dass du mich auf Stellen in meiner angegebenen Quelle hinweist, aber da bist du schon an der entscheidenden Stelle vorbei:
CLOSQLCSR defines how the programs handles cursors within the embedded SQL programs. It does not have any bearing on how ODPs are created, maintained, or reused.
(bearing würde ich hier als Einfluss übersetzen, aber auch da lasse ich mit mir reden!)
IBM hält sich mit Dokumentation ziemlich bedeckt, was maintenance, creation und reuse von ODPs angeht und da ich davon ausgehe, dass ILE und OPM dieselben APIs benutzen und sich dieses dokumentierte Verhalten auch mit meinen Erfahrungen mit ILE deckt, warte ich immer noch auf aktuellere Information, was länger dauern kann (siehe MI Reference)
D*B
Ist Dir auch aufgefallen, dass in dem Dokument 6492409 nur von RPGIII geredet wurde und nicht RPGIV oder ILERPG.
Die Optionen *ENDPGM, *ENDJOB und *ENDSQL können nur bei CRTSQLRPG (sprich RPGIII) und nicht bei CRTSQLRPGI (sprich RPGIV) angegeben werden. Bei CRTSQLRPGI heißen die Optionen *ENDMOD und *ENDACTGRP.
In ILE funktioniert die Option *ENDMOD wie *ENDPGM, während bei der Option *ENDACTGRP der ODP geöffnet bleibt und wiederverwendbar ist, solange die Aktivierungsgruppe nicht beendet wird.
Aus dem Dokument 6492409:
Damit wird auch beim *ENDMOD der ODP gelöscht (discarded = weggeworfen).
Dokumentationen über CLOSQLCSR findet man in der Online Library in Database Performance and Query Optiomization:
General rules for retaining cursor positions for all program calls (http://publib.boulder.ibm.com/infocenter/systems/scope/i5os/index.jsp?topic=/rzajq/retrs.htm&tocNode=int_98251)
Birgitta
Danke für die ausführlichen Antworten!
Ich werde in diesem Fall das Modul mit der Option *ENDMOD wandeln und die Perfomanceeinbusse in Kauf nehmen, da es Gewährleistet sein muss, dass nach dem Lesen der Daten keinerlei Sperren zurück bleiben.
Joe