ISAM-Dateien mit indizierter oder relativer Dateiorganisation können für mehrere Benutzer gleichzeitig zugänglich gemacht werden. Dies geschieht mit dem Operanden SHARED-UPDATE im SUPPORT-Parameter des ADD-FILE-LINK-Kommandos:
/ADD-FILE-LINK linkname,dateiname,SUPPORT=DISK(SHARED-UPDATE=YES)
Die folgende Tabelle zeigt, welche OPEN-Anweisungen für einen Benutzer B möglich sind, nachdem die Datei von Benutzer A bereits eröffnet wurde.
Zulässige Angaben für Benutzer B | |||||||
Von Benutzer A | OPEN- | SHARED-UPDATE=YES | SHARED-UPDATE=NO | ||||
SHARED-UPDATE=YES | INPUT | I-O | OUPUT/ | INPUT | I-O | OUTPUT/ | |
INPUT | X | X | X | ||||
I-O | X | X | |||||
OUTPUT/EXTEND | |||||||
SHARED-UPDATE=NO | INPUT | X | X | ||||
I-0 | |||||||
OUTPUT/EXTEND |
Tabelle 35: Zulässige OPEN-Anweisungen bei Simultanverarbeitung
X = zulässige Kombinationen von OPEN-Anweisung und SHARED-UPDATE-Angabe
Aus der Tabelle geht hervor, dass die Angabe von SHARED-UPDATE=YES für INPUT-Dateien überflüssig ist, falls alle Anwender OPEN INPUT verwenden.
Wenn SHARED-UPDATE=YES für INPUT-Dateien trotzdem angegeben werden muss, da mindestens ein Anwender OPEN I-O verwendet, wird das nachfolgend beschriebene Sperren bzw. Entsperren nicht durchgeführt.
Die Angabe SHARED-UPDATE=YES ist nur für die gleichzeitige Aktualisierung von einer oder mehreren ISAM-Dateien (OPEN I-O) durch zwei oder mehr Dialogbenutzer sinnvoll und auch notwendig.
Aktualisierungen im Stapelbetrieb sollten nacheinander ablaufen, um sowohl Logikfehler als auch Laufzeitverlängerungen zu vermeiden (unnötige Angabe von SHARED-UPDATE=YES kostet Laufzeit und CPU-Zeit).
Bei Angabe von SHARED-UPDATE=YES wird automatisch auch WRITE-CHECK=YES gesetzt, d.h. die ISAM-Puffer werden nach jeder Änderung sofort zurückgeschrieben. Dies ist aus Datensicherheits- und Eindeutigkeitsgründen erforderlich, erhöht aber wesentlich die Anzahl der Ein-/Ausgaben.
Um Datenkonsistenz bei gleichzeitiger Aktualisierung einer ISAM-Datei durch mehrere Benutzer zu gewährleisten, benutzt das COBOL2000-Laufzeitsystem den Sperr- und Entsperrmechanismus der DVS-Zugriffsmethode ISAM. Dieser Mechanismus sorgt für das Sperren bzw. Entsperren der Datenblöcke, in denen die durch die Anweisungen READ, WRITE, REWRITE oder DELETE angesprochenen Datensätze liegen.
Ein Datenblock ist das Vielfache einer PAM-Seite (2048 Byte), das durch den BUFFER-LENGTH-Parameter im ADD-FILE-LINK-Kommando implizit oder explizit beim Erzeugen der Datei vereinbart wurde (siehe Abschnitt „Grundbegriffe zum Aufbau von Dateien").
Ist Im Folgenden von Datensatzsperre die Rede, ist immer die Sperre des ganzen Blocks, in dem dieser Datensatz liegt, gemeint.
Für die Simultanverarbeitung von ISAM-Dateien gibt es eine Formaterweiterung der READ- bzw. START-Anweisung, die jedoch nur wirksam wird, wenn im ADD-FILE-LINK-Kommando SHARED-UPDATE=YES angegeben und die Datei mit OPEN I-O eröffnet ist.
Formaterweiterung für alle Formate:
READ dateiname [WITH NO LOCK]...
START dateiname [WITH NO LOCK]...
Regeln für die Simultanaktualisierung
READ- oder START-Anweisung mit WITH NO LOCK-Zusatz:
Gibt Benutzer A WITH NO LOCK an und ist der entsprechende Datensatz vorhanden, wird dieser gelesen bzw. wird auf diesen positioniert, ungeachtet einer etwa durch einen anderen Benutzer bereits gesetzten Sperre. Der Datensatz wird nicht gesperrt. Eine REWRITE- bzw. DELETE-Anweisung kann auf einen so gelesenen Satz nicht ausgeführt werden.
Ein simultaner Benutzer B kann denselben Datensatz sowohl lesen als auch aktualisieren.
READ- oder START-Anweisung ohne WITH NO LOCK-Zusatz:
Gibt Benutzer A WITH NO LOCK nicht an und ist der entsprechende Datensatz vorhanden, kann eine READ- bzw. START-Anweisung nur dann erfolgreich ausgeführt werden, wenn der entsprechende Datensatz nicht bereits durch Benutzer B gesperrt ist. War die Ausführung der Anweisung erfolgreich, wird der Datensatz gesperrt. Vor Aufhebung der Sperre kann Benutzer B denselben oder irgendeinen anderen Datensatz desselben Datenblocks nur mit WITH NO LOCK lesen oder auf ihn positionieren, er kann aber keinen Datensatz dieses Datenblocks aktualisieren. (Hat Benutzer B die Datei mit OPEN INPUT eröffnet, kann er Sätze des gesperrten Datenblocks immer lesen.)
Aktualisierung von Datensätzen:
Soll durch eine REWRITE- oder DELETE-Anweisung ein Datensatz aktualisiert werden, muss der betroffene Datensatz unmittelbar zuvor durch eine READ-Anweisung (ohne WITH NO LOCK-Zusatz!) gelesen werden. Nach dieser READ- und vor der REWRITE- bzw. DELETE-Anweisung darf für dieselbe ISAM-Datei keine weitere Ein-/Ausgabeanweisung ausgeführt werden. Zwischen diesen beiden Anweisungen dürfen für andere ISAM-Dateien, deren ADD-FILE-LINK-Kommando SHARED-UP-DATE=YES enthält und die zur gleichen Zeit mit OPEN I-O eröffnet sind, nur READ- oder START-Anweisungen mit WITH NO LOCK-Zusatz ausgeführt werden. Anweisungen für andere ISAM-Dateien (ohne SHARED-UPDATE=YES und OPEN I-O) dürfen ausgeführt werden.
Ein Verstoß gegen diese Vorschriften führt zu einer erfolglosen REWRITE- bzw. DELETE-Anweisung mit FILE STATUS 94.Wartezeiten bei einer Sperre:
Hat Benutzer A auf Grund einer erfolgreich ausgeführten READ- oder START-Anweisung einen Datensatz gesperrt und versucht Benutzer B auf denselben Datensatz oder irgendeinen anderen aus demselben Datenblock eine READ- oder START-Anweisung ohne WITH NO LOCK-Zusatz auszuführen, so führt dies für letzteren nicht sofort zum Mißerfolg. Benutzer B wird in eine Warteschlange eingeordnet, in der er auf die Freigabe der Sperre durch Benutzer A wartet. Erst wenn eine maximale Wartezeit abgelaufen und die Entsperrung innerhalb dieser Frist nicht erfolgt ist, gilt die Anweisung als erfolglos und FILE STATUS 93 wird gesetzt. Wurde die Sperre vor Ablauf der Wartezeit aufgehoben, so kann Benutzer B mit dem erfolgreichen Aufruf fortfahren.
Freigabe eines gesperrten Datensatzes:
Ein Benutzer behält eine Datensatzsperre solange bei, bis er eine der folgenden Anweisungen ausführt:
erfolgreiche REWRITE- oder DELETE-Anweisung auf den gesperrten Datensatz
WRITE-Anweisung auf eine ISAM-Datei, deren ADD-FILE-LINK-Kommando SHARED-UPDATE=YES enthält und die mit OPEN I-O eröffnet ist (d.h. auf dieselbe Datei, die den gesperrten Datensatz enthält, oder auf eine andere ISAM-Datei; Entsperrung erfolgt auch bei Auftreten der INVALID KEY-Bedingung)
READ- oder START-Anweisung mit WITH NO LOCK-Zusatz auf dieselbe Datei (Entsperrung erfolgt auch bei Auftreten der AT END- oder INVALID KEY-Bedingung)
READ- oder START-Anweisung ohne WITH NO LOCK-Zusatz auf einen Datensatz innerhalb eines anderen Datenblocks derselben Datei (Entsperrung erfolgt auch bei Auftreten der AT END- oder INVALID KEY-Bedingung)
READ- oder START-Anweisung ohne WITH NO LOCK-Zusatz auf eine andere ISAM-Datei, deren ADD-FILE-LINK-Kommando SHARED-UPDATE=YES enthält und die mit OPEN I-O eröffnet ist (Entsperrung erfolgt auch bei Auftreten der AT END- oder INVALID KEY-Bedingung)
CLOSE-Anweisung für dieselbe Datei.
Eine Anweisung für eine ISAM-Datei kann also die Aufhebung einer Datensatzsperre auf einer anderen ISAM-Datei bewirken.
Hinweise
Soll in einem Programm eine ISAM-Datei (SHARED-UPDATE=YES und OPEN I-O) bearbeitet werden, sollte für diese Datei eine USE AFTER STANDARD ERROR-Prozedur vorgesehen werden. In dieser Prozedur können die simultanverarbeitungsspezifischen FILE STATUS-Werte 93 (Datensatz von einem simultanen Benutzer gerade gesperrt) und 94 (REWRITE- oder DELETE-Anweisung ohne vorherige READ-Anweisung) abgefragt und angemessen verarbeitet werden.
Es sollte immer berücksichtigt werden, dass auf Grund des Block-Sperrmechanismus von ISAM beim Sperren eines Datensatzes auch zugleich alle Datensätze desselben Blocks für alle simultanen Benutzer gesperrt werden.
Für einen Benutzer kann höchstens ein Datenblock gesperrt, d.h., vor Aktualisierung durch andere Benutzer geschützt sein. Dies gilt auch dann, wenn er mehrere ISAM-Dateien (alle SHARED-UPDATE=YES) im Modus OPEN I-O eröffnet hat.
Eine „Deadlock“-Situation (gegenseitiges Sperren von Datenblöcken durch verschiedene Benutzer) ist ausgeschlossen, da für jeden Benutzer nur ein einziger Block aller ISAM-Dateien (alle SHARED-UPDATE=YES) gesperrt sein kann. Dies gilt jedoch nicht, wenn gleichzeitig auf eine PAM-Datei mit SHARED-UPDATE=YES im I-O-Modus zugegriffen wird!
Falls zwischen einer READ- und einer REWRITE- bzw. DELETE-Anweisung für einen Datensatz ein Zugriff auf einen anderen Datenblock derselben oder einer anderen ISAM-Datei erfolgt, der gleichzeitig eine Entsperrung des zuvor gesperrten Datenblocks zur Folge hat, muss der Datensatz vor Ausführung der REWRITE- bzw. DELETE-Anweisung noch einmal gelesen werden. Da der betroffene Datenblock in der Zwischenzeit für andere Benutzer entsperrt war, könnte der Inhalt des Datensatzes verändert worden sein (siehe Beispiel 9-12a).
Erfolgt der Zugriff auf den anderen Datenblock bzw. die andere Datei ohne Sperrmechanismus, könnten die dadurch bereitgestellten Daten während der Verarbeitung bereits wieder durch simultane Benutzer verändert worden sein, ehe die REWRITE- bzw. DELETE-Anweisung ausgeführt worden ist (siehe Beispiel 9-12b).
Um zu vermeiden, dass ein Benutzer möglicherweise mit nicht mehr aktuellen Daten arbeitet, sollte der WITH NO LOCK-Zusatz nur dann verwendet werden, wenn dies unbedingt erforderlich ist.
Ein gesperrter Datensatz (Datenblock) führt bei simultanen Benutzern, die auf denselben Datensatz oder einen anderen desselben Blocks zugreifen wollen, zu Wartezeiten. Um diese so kurz wie möglich zu halten, sollte die Sperre sobald wie möglich wieder aufgehoben werden. Wird die Sperre nicht rechtzeitig aufgehoben, läuft die Wartezeit ab, und das Programm verzweigt in die vorgesehene USE-Prozedur, sofern vorhanden (siehe Beispiel 9-13) oder wird abgebrochen (mit Meldung COB9151, FILE STATUS 93 und DVS-Fehlerschlüssel DAAA).
Beispiel 9-12
Lesen und Zurückschreiben in Datei ISAM1, wenn vor dem Zurückschreiben Daten aus einer Datei ISAM2 benötigt werden
Ohne WITH NO LOCK-Zusatz: zweimalige READ-Anweisung auf dieselbe Datei erforderlich, dafür Sperrzeiten kürzer:
...
READ ISAM1 INTO WORK1 —————————————————————————————————————————————————(1)
INVALID KEY...
...
READ ISAM2 ————————————————————————————————————————————————————————————(2)
INVALID KEY...
...
Verarbeitung von WORK1 unter Berücksichtigung von ISAM2SATZ
...
READ ISAM1 ————————————————————————————————————————————————————————————(3)
INVALID KEY...
Prüfung, ob ISAM1SATZ inzwischen geändert, gegebenenfalls erneute Verarbeitung
...
REWRITE ISAM1SATZ FROM WORK1———————————————————————————————————————————(4)
INVALID KEY...
(1)
Lesen eines Datensatzes aus ISAM1 und Zwischenspeichern in WORK1, betroffener Datenblock in ISAM1 gesperrt
(2)
Lesen eines Datensatzes aus ISAM2, Aufhebung der Sperre in ISAM1, Sperrung des betroffenen Datenblocks in ISAM2
(3)
Erneutes Lesen des Datensatzes in ISAM1, Aufhebung der Sperre in ISAM2, Sperrung des betroffenen Datenblocks in ISAM1
(4)
Zurückschreiben des Datensatzes nach ISAM1, Aufhebung der Sperre in ISAM1
Mit WITH NO LOCK-Zusatz: nur eine READ-Anweisung auf dieselbe Datei erforderlich, dafür Sperrzeiten länger:
...
READ ISAM1 ———————————————————————————————————————————————————————————(1)
INVALID KEY...
...
READ ISAM2 WITH NO LOCK ——————————————————————————————————————————————(2)
INVALID KEY...
...
Verarbeitung von ISAM1SATZ unter Berücksichtigung von ISAM2SATZ
...
REWRITE ISAM1SATZ FROM WORK1——————————————————————————————————————————(3)
INVALID KEY...
(1)
Lesen eines Datensatzes aus ISAM1, betroffener Datenblock gesperrt
(2)
Lesen eines Datensatzes aus ISAM2, betroffener Datenblock nicht gesperrt
(3)
Zurückschreiben des Datensatzes nach ISAM1, Sperre wird aufgehoben
Beispiel 9-13
Verzweigen zu einer USE AFTER STANDARD ERROR-Prozedur
... FILE-CONTROL. SELECT ISAM1 ... FILE STATUS IS FILESTAT1. WORKING-STORAGE SECTION. 77 FILESTAT1 PIC 99. ... PROCEDURE DIVISION. DECLARATIVES. ISAM1ERR SECTION. USE AFTER STANDARD ERROR PROCEDURE ON ISAM1. SPERRE. IF FILESTAT1 = 93 THEN DISPLAY "SATZ ZUR ZEIT GESPERRT" UPON T ELSE DISPLAY "DMS-FEHLER ISAM1, FILE-STATUS=" FILESTAT1 UPON T. ISAM1ERR-EX. EXIT. ——————————————————————————————————————————————————————————————(1) END DECLARATIVES. STEUER SECTION. ...
(1) | Verzweigen auf die Anweisung hinter der fehlerverursachenden Anweisung. |