PDA

View Full Version : SQLRPGLE und offene Dateien



Tonazzo
13-06-14, 21:31
Hallo zusammen,

habe mal wieder eine Frage.
Es geht um ein SQLRPGLE - im Programm wird mit SELECT, UPDATE FETCH usw. gearbeitet.
Mit F3 wird das Programm beendet und *INLR wird auf *ON gesetzt.
Soweit so gut......

Allerdings sieht man bei DSPJOB #14 (offene Dateien), dass die Dateien jedoch noch
offen sind :confused:. Teilweise werden diese sogar mehrfach als offen angezeigt. Hängt das vielleicht mit Activation Groups zusammen und wie kann man das
Problem lösen?

Viele Dank im Voraus....

malzusrex
13-06-14, 21:42
Beim Verlassen des Programmes


c/exec sql
c+ Set Option CloSqlCsr = *EndMod
c/end-exec


Damit sollten alle offene Zugriffspfade geschlossen werden

Gruß
Ronald

BenderD
14-06-14, 07:11
... das ist ein typischer Fall von denkste (das mit dem CloSQLCsr)!
SQL versucht seit etlichen Releases von DB2/400 Zugriffspfade offen zu halten - und das ist auch gut so, weil es Ressourcen schont und Geschwindigkeit bringt. Wenn ein anderer Datenbank Connect eine Ressource konkurrierend für einen SQL Zugriff benötigt und die Sperre stört, wird sie, wenn möglich, freigegeben. Damit das reibungslos klappt, dürfen im jeweiligen Programm keine unnötigen Sperren gehalten werden.
Am einfachsten geht das mit Commitment Controll!!! Bei Beendigung einer Transaktion schließt man selbige mit COMMIT oder ROLLBACK und das wars.
Für all diejenigen, die meinen, dass es ohne Commit einfacher wäre, wird es ein wenig schwieriger!!! Da hält nämlich ein Cursor for update nach dem fetch eine Satzsperre, was eine automatische Freigabe verhindert. Das lässt sich korrekterweise vermeiden, indem man den cursor schließt. Am Besten macht man das mit explicitem close im Programm (dann weiß man nämlich, dass man den vor nächster Benutzung wieder aufmachen muss. Die Clo Anweisung (siehe Roland) macht das bei verlassen des Moduls automatisch. In beiden Fällen erfolgt ein Pseudo Close, sprich: die Datenbank merkt sich, dass der Benutzer Close gesagt hat und lässt den Zugriffspfad offen (weiß aber, dass sie den zumachen könnte, wenn sie wollte). In beiden Fällen sieht man die Sperren auf Dateiebene im Job!!! Der Nachteil bei der Clo Anweisung mit dem endmod ist, dass man leicht vergisst bei nächster Benutzung open zu sagen, bevor man fetch sagen darf (sonst gibt es Einwände in Form von negativem SQL Code).
Sagt der Benutzer jetzt wieder open für denselben Cursor, denkt sich die Datenbank: "Hab ich mir doch gleich gedacht" und tut so als ob sie den Zugriffspfad wieder aufmacht, braucht aber nix zu machen, was schnell geht.
Die einzige Möglichkeit die Ressourcen wirklich wegzubekommen war klassischer Weise ein disconnect, wobei ich mir nicht einmal sicher bin, ob selbst diese radikale Maßnahme unter neuren Releases noch wirkt (habe ich lange nicht untersucht, weil die offenen Zugriffspfade im Normalfall nicht stören.
Bleibt noch die Frage: was ist der Unnormalfall, wo das stören könnte. Wenn man Operationen hat für die man Ressourcen exclusiv braucht, dann kann das stören. Das könnte z.B. ein RGZPFM, oder ein Delete File oder ENDJRNPF oder ähnliches sein; für diese Fälle gibt es einen Parameter beim ALCOBJ CONFLICT(*RQSRLS) , der dann Sperren wg. Pseudo close wegräumt. Den selteneren Fall, dass jemand bei commitment controll Sperrlevel serialize verwendet, den habe ich im Fall von DB2/400 noch nie gesehen (obwohl das der SQL Standard eigentlich vorsieht!!!) und das kann die DB2/400 eigentlich auch nicht wirklich.

D*B

PS: der oft in den Raum gestellte Performance Unterschied bei der Clo Anweisung zwischen Endmod und ENDACTGRP ist blanker Schmäh und hat mit dem wirklichen Leben nix zu tun, letzteres hält sich halt nicht an Handbücher und Mythen.

Fuerchau
14-06-14, 09:31
Und was die ODP's angeht habe ich auch festgestellt, dass diese automatisch geschlossen werden, wenn ich von einem anderen Job ein CHGPF/RGZPF/DLTF/DROP TABLE o.ä. mache.

andreaspr@aon.at
16-06-14, 07:36
Wie Dieter schon sagte, it's not a bug it's a feature.

Mit den folgenden QAQQINI Parametern kann man angeben, ab wann die Cursor hart geschlossen werden sollen:
OPEN_CURSOR_CLOSE_COUNT
OPEN_CURSOR_THRESHOLD

Jedoch bei sauberer Programmierung (z.B. kein ACTGRP(*NEW)) lässt man die DB besser so, da es durchaus Sinn macht.
Und bei einem ALTER/DROP TABLE oder sonst was, erkennt die DB die Sperren automatisch und schließt diese.

lg Andreas

BenderD
16-06-14, 09:30
... mit OPEN_CURSOR_THRESHOLD wäre ich extrem vorsichtig - die Doku hält sich da irgendwie leicht bedeckt, ob das nicht zu Problemen führt, wenn man tatsächlich mehr offene Cursor braucht und beim prepare once, open multiple times ist der generierte Code vom embedded SQL sehr sparsam.
Das mit der ACTGRP(*NEW) wirkt in diesem Kontext genau umgekehrt wie du unterlegst: Die Connection wird beim Ende des Programms implizit geschlossen, was in jedem Fall zur Freigabe von Ressourcen incl. Hard closes führt.

D*B

Wie Dieter schon sagte, it's not a bug it's a feature.

Mit den folgenden QAQQINI Parametern kann man angeben, ab wann die Cursor hart geschlossen werden sollen:
OPEN_CURSOR_CLOSE_COUNT
OPEN_CURSOR_THRESHOLD

Jedoch bei sauberer Programmierung (z.B. kein ACTGRP(*NEW)) lässt man die DB besser so, da es durchaus Sinn macht.
Und bei einem ALTER/DROP TABLE oder sonst was, erkennt die DB die Sperren automatisch und schließt diese.

lg Andreas