Version 11 (Geändert)
4D und 4D Server verwalten die Datenbanken automatisch bei Mehrfachbenutzung. Zwei Benutzer bzw. zwei Prozesse können nicht gleichzeitig denselben Datensatz oder dasselbe Objekt ändern. Der zweite Benutzer bzw. Prozess kann zur selben Zeit nur im Lesemodus darauf zugreifen.
Multi-User Befehle bieten sich an, wenn Sie:
Datensätze per Programmierung ändern.
Eine eigene Benutzeroberfläche für Operationen im Mehrplatzbetrieb einsetzen.
Verknüpfte Änderungen innerhalb einer Transaktion sichern.
Setzen Sie eine Datenbank in der Multiprozess-Umgebung ein, müssen Sie folgendes beachten:
Jede Tabelle befindet sich entweder im Lesemodus oder im Lese-/Schreibmodus.
Geladene Datensätze werden gesperrt, abgelegte Datensätze werden wieder freigegeben.
Ein gesperrter Datensatz kann nicht geändert werden.
In den folgenden Abschnitten gilt folgende Sprachregelung:
Die Person, die eine Operation in der Datenbank im Mehrplatzbetrieb ausführt, wird lokaler Benutzer genannt. Die anderen Benutzer der Datenbank werden andere Benutzer genannt. Analog dazu wird der Prozess, der in der Multiprozessumgebung eine Operation ausführt, aktueller Prozess genannt. Alle anderen Prozesse in Ausführung werden andere Prozesse genannt. Die Erläuterungen erfolgen aus der Sicht des lokalen Benutzers und des laufenden Prozesses.
Gesperrte Datensätze
Eine gesperrter Datensatz kann weder vom lokalen Benutzer noch vom laufenden Prozess geändert werden. Er kann geladen, jedoch nicht geändert werden. Ein Datensatz ist gesperrt, sobald einer der anderen Benutzer oder Prozesse diesen im Lese-/Schreibmodus geladen hat. Nur der Benutzer, der den Datensatz ändert, sieht ihn als nicht gesperrt. Für alle anderen Benutzer und Prozesse erscheint dieser Datensatz als gesperrt. Sie können keine Änderungen vornehmen. Der Datensatz hat nur dann den Status nicht gesperrt, wenn die dazuhörige Tabelle im Lese-/Schreibmodus ist.
Nur-Lesen und Lese-/Schreibmodus
Jede Tabelle in einer Anwendung ist entweder im Lese-/Schreibmodus oder Nur-Lesen für jeden Benutzer und jeden Prozess der Datenbank. Nur-Lesen bedeutet, dass die Datensätze einer Tabelle geladen, aber nicht geändert werden können. Lesen/Schreiben bedeutet, dass Datensätze für die Tabelle geladen und geändert werden können, wenn kein anderer Benutzer den Datensatz zuvor gesperrt hat.
Wenn Sie den Status einer Tabelle ändern, wirkt sich die Änderung auf den nächsten geladenen Datensatz aus. Sie gilt nicht für den aktuell geladenen Datensatz
Status Nur-Lesen
Ist eine Tabelle im Modus Nur-Lesen und wird ein Datensatz geladen, ist der Datensatz immer gesperrt, d.h. er lässt sich anzeigen, drucken oder anderweitig nutzen, aber nicht verändern.
Der Status Nur-Lesen gilt nur für das Bearbeiten vorhandener Datensätze, er hat keine Auswirkung auf das Erstellen neuer Datensätze. In einer Tabelle im Modus Nur-Lesen können Sie Datensätze über die Befehle CREATE RECORD und ADD RECORD oder über die Menübefehle der Designumgebung hinzufügen.
4D setzt eine Tabelle für Befehle, die keinen Schreibzugriff auf Datensätze benötigen, automatisch auf Nur-Lesen. Das sind folgende Befehle:
Den Status einer Tabelle können Sie jederzeit mit der Funktion Read only state herausfinden.
Vor der Ausführung einer dieser Befehle sichert 4D den aktuellen Status der Tabelle (Lesemodus oder Lese-/Schreibmodus) für den laufenden Prozess . Dieser Status wird nach Ausführung des Befehls wiederhergestellt.
Status Lesen/Schreiben
Ist eine Tabelle im Lese-/Schreibmodus und wird ein Datensatz geladen, wird der Datensatz entsperrt, wenn ihn zuvor kein anderer Benutzer gesperrt hat. Ist der Datensatz von einem anderen Benutzer gesperrt, wird er als gesperrt geladen und kann vom lokalen Benutzer nicht verändert werden.
Eine Tabelle muss in den Lese-/Schreibmodus gesetzt werden, damit der geladene Datensatz entsperrt wird und änderbar ist.
Lädt ein Benutzer einen Datensatz von einer Tabelle im Lese-/Schreibmodus, kann kein anderer Benutzer diesen Datensatz zum Ändern laden. Er kann jedoch in der Tabelle Datensätze hinzufügen, entweder über die Befehle CREATE RECORD oder ADD RECORD oder manuell in der Designumgebung.
Alle Tabellen sind standardmäßig im Lese-/Schreibmodus, wenn eine Datenbank geöffnet und ein neuer Prozess gestartet wird.
Status einer Tabelle ändern
Sie können den Status einer Tabelle über die Befehle READ ONLY und READ WRITE ändern. Wollen Sie den Status einer Tabelle ändern, um einen Datensatz auf Nur-Lesen oder Lesen/Schreiben zu setzen, müssen Sie den Befehl vor Laden des Datensatzes ausführen. Die Befehle READ ONLY und READ WRITE gelten nicht für den bereits geladenen Datensatz.
Jeder Prozess hat seinen eigenen Status (Nur-Lesen oder Lesen/Schreiben) für jede Tabelle in der Datenbank
Datensätze ändern, aktualisieren, freigeben
Bevor ein lokaler Benutzer einen Datensatz ändern kann, muss die Tabelle im Status Lesen/Schreiben sein und der Datensatz geladen und entsperrt sein.
Jeder Befehl, der einen aktuellen Datensatz lädt, wie NEXT RECORD, QUERY, ORDER BY, RELATE ONE, etc., setzt den Datensatz auf gesperrt oder entsperrt. Der Datensatz wird gemäß dem aktuellen Status seiner Tabelle (Nur-Lesen oder Lesen/Schreiben) und seiner Verfügbarkeit geladen. Es kann auch ein Datensatz einer verknüpften Tabelle geladen werden, wenn einer der Befehle eine automatische Verknüpfung auslöst.
Ist eine Tabelle im Nur-Lesen Status, ist der geladene Datensatz gesperrt. Ein gesperrter Datensatz kann von einem anderen Prozess weder gesichert noch gelöscht werden.
Ist eine Tabelle im Lesen/Schreiben Status, ist der geladene Datensatz nur dann nicht gesperrt, wenn er nicht zuvor durch einen anderen Benutzer gesperrt wurde. Ein nicht gesperrter Datensatz lässt sich ändern und sichern. Eine Tabelle sollte in den Lesen/Schreiben Status gesetzt werden, bevor ein Datensatz geladen, geändert und gesichert wird.
Um sicher zu gehen, dass Sie einen Datensatz im Lese-/Schreibmodus erhalten, führen Sie nacheinander folgende Operationen durch:
Greifen Sie auf die Tabelle mit dem Befehl READ WRITE zu.
Rufen Sie den gewünschten Befehl auf, der den Datensatz zum ersten Mal lädt, beispielsweise NEXT RECORD, QUERY, ORDER BY, RELATE ONE.
Prüfen Sie mit der Funktion Locked den Zustand des Datensatzes.
Ist der Datensatz gesperrt, rufen Sie mit den Befehl LOAD RECORD den Datensatz so lange auf, bis Locked den Wert FALSE zurückgibt.
Ändern Sie den Datensatz.
Sichern Sie ihn und geben ihn dann frei, indem Sie den aktuellen Datensatz wechseln oder mit dem Befehl UNLOAD RECORD freigeben.
Hinweis: Wird UNLOAD RECORD in einer Transaktion verwendet, entsperrt er den aktuellen Datensatz nur für den Prozess, der diese Transaktion verwaltet. Für andere Prozesse bleibt der Datensatz gesperrt, bis die Transaktion bestätigt oder annulliert wurde.
Verwenden Sie den Befehl LOCKED ATTRIBUTES, um feststellen, welcher Benutzer bzw. Prozess einen Datensatz gesperrt hat.
Schleifen zum Laden freigegebener Datensätze
Folgendes Beispiel zeigt die einfachste Schleife zum Laden eines ungesperrten Datensatzes:
READ WRITE ([Customers]) ` Setze Tabelle auf Lese-/Schreibmodus Repeat ` Durchlaufe Schleife, bis Datensatz freigegeben ist LOAD RECORD ([Customers]) ` Lade Datensatz und setze Status gesperrt Until (Not (Locked([Customers]))) ` Bearbeite diesen Datensatz READ ONLY ([Customers]) ` Setze Tabelle auf Nur Lesen
Die Schleife läuft solange, bis der Datensatz freigegeben ist.
Diese Schleife wird nur verwendet, wenn Sie davon ausgehen können, dass der Datensatz nicht durch jemand anderen gesperrt ist. Denn der Benutzer muss das Beenden der Schleife abwarten. Der Fall ist relativ unwahrscheinlich, da der Datensatz nur über eine Methode geändert werden kann.
Folgendes Beispiel verwendet die obige Schleife, um einen ungesperrten Datensatz zu laden und anschließend zu ändern:
READ WRITE([Inventory]) Repeat ` Durchlaufe Schleife, bis Datensatz freigegeben ist LOAD RECORD([Inventory]) ` Lade Datensatz und setze Status gesperrt Until (Not (Locked([Inventory]))) [Inventory]Part Qty := [Inventory]Part Qty 1 ` Ändere Datensatz SAVE RECORD ([Inventory]) ` Sichere Datensatz UNLOAD RECORD ([Inventory]) ` Lass andere Benutzer den Datensatz ändern READ ONLY([Inventory])
Der Befehl MODIFY RECORD zeigt dem Benutzer automatisch an, ob der Datensatz gesperrt ist und unterbindet so eine Änderung. Folgendes Beispiel umgeht diese automatische Anzeige durch den Test mit der Funktion Locked. Ist der Datensatz gesperrt, kann der Benutzer abbrechen.
Dieses Beispiel prüft in optimaler Weise, ob der aktuelle Datensatz für die Tabelle [Commands] gesperrt ist. Wenn ja, wird der Prozess von der Methode um eine Sekunde verschoben. Diese Technik können Sie sowohl in der Multi-User- als auch in der Multiprozessumgebung einsetzen:
Repeat READ ONLY([Commands]) ` Sie benötigen Lese-/Schreibmodus gerade nicht QUERY([Commands]) ` Wurde die Suche abgeschlossen und einige Datensätze zurückgegeben If ((OK=1) & (Records in selection([Commands])>0)) READ WRITE([Commands]) ` Setze Tabelle auf Lese-/Schreibmodus LOAD RECORD([Commands]) While (Locked([Commands]) & (OK=1)) `Ist der Datensatz gesperrt, ` durchlaufe Schleife, bis Datensatz freigegeben ist ` Wer sperrt den Datensatz? LOCKED ATTRIBUTES([Commands];$Process;$User;$Machine;$Name) If ($Process=-1) ` Wurde der Datensatz gelöscht? ALERT("Datensatz wurde inzwischen gelöscht.") OK:=0 Else If ($User="") ` Sind Sie im Einzelplatzbetrieb $User:="Ihnen" End if CONFIRM("Datensatz wird bereits von "+$User+" im Prozess "+$Name+" verwendet.") If (OK=1) ` Wollen Sie ein paar Sekunden warten? DELAY PROCESS(Current process;120) ` Warten Sie ein paar Sekunden LOAD RECORD([Commands])` Versuchen Sie, Datensatz zu laden. End if End if End while If (OK=1) ` Datensatz ist freigegeben MODIFY RECORD([Commands]) ` Sie können Datensatz ändern UNLOAD RECORD([Commands]) End if READ ONLY([Commands]) ` Wechsle wieder in Modus Nur Lesen OK:=1 End if Until (OK=0)
Befehle im Mehrplatzbetrieb bzw. in der Multiprozessumgebung
Ein Reihe von Befehlen der Programmiersprache arbeiten bei ungesperrten Datensätzen normal. Treffen sie auf einen gesperrten Datensatz, führen sie ganz bestimmte Aktionen aus. Es handelt sich um folgende Befehle:
MODIFY RECORD: Meldet, dass der Datensatz bereits benutzt wird. Der Datensatz wird nicht angezeigt, der Benutzer kann ihn also nicht ändern. In der Benutzerumgebung erscheint der Datensatz im Modus Nur Lesen.
MODIFY SELECTION: Arbeitet normal, durch Doppelklick kann der Benutzer den Datensatz ändern. Ist er gesperrt, meldet MODIFY SELECTION, dass der Datensatz bereits benutzt wird. Der Datensatz ist dann nur im Modus Nur Lesen verfügbar
APPLY TO SELECTION: Lädt einen gesperrten Datensatz, ändert ihn jedoch nicht. Mit APPLY TO SELECTION können Sie so Informationen ohne Risiko aus Tabellen auslesen. Gesperrte Datensätze werden in der Menge LockedSet abgelegt.
DELETE SELECTION: Löscht keine gesperrten Datensätze; sie werden übersprungen. Gesperrte Datensätze werden in der Menge LockedSet abgelegt.
DELETE RECORD: Wird bei gesperrtem Datensatz nicht ausgeführt. Es erscheint keine Fehlermeldung. Sie müssen vor Ausführung dieses Befehls prüfen, ob der Datensatz freigegeben ist.
SAVE RECORD: Wird bei gesperrtem Datensatz nicht ausgeführt. Es erscheint keine Fehlermeldung. Sie müssen vor Ausführung dieses Befehls prüfen, ob der Datensatz freigegeben ist.
ARRAY TO SELECTION: Sichert keine gesperrten Datensätze. Gesperrte Datensätze werden in der Menge LockedSet abgelegt.
GOTO RECORD: In einer Datenbank in der Multi-User-/Multiprozess-Umgebung können andere Benutzer Datensätze löschen bzw. hinzufügen. So können sich auch die Datensatznummern verändern. Seien Sie also vorsichtig, wenn Sie im Mehrplatzbetrieb auf einen Datensatz über seine Nummer zugreifen.
Mengen: Behandeln Sie Mengen mit Vorsicht, da andere Benutzer oder Prozesse die darin enthaltenen Informationen bereits geändert haben können.
Referenz
LOAD RECORD, Locked, LOCKED ATTRIBUTES, Methoden, READ ONLY, Read only state, READ WRITE, UNLOAD RECORD, Variablen.