Oftmals müssen Sie Konflikte verwalten, die auftreten können, wenn mehrere Benutzer oder Prozesse die gleichen Entities zur selben Zeit laden und versuchen zu ändern. In relationalen Datenbanken ist Datensatz-Sperren eine Vorgehensweise, um inkonstistente Aktualisierung von Daten zu vermeiden. Das Konzept dahinter ist, entweder einen Datensatz auf Nur-Lesen Modus zu setzen, so dass kein anderer Prozess ihn ändern kann, oder beim Sichern des Datensatzes zu prüfen, dass ihn kein anderer Prozess seit dem Laden geändert hat. Die erste Vorgehensweise wird als pessimistisches Datensatz-Sperren bezeichnet. Sie stellt sicher, dass ein geänderter Datensatz geschrieben werden kann und für andere Benutzer gesperrt ist. Die zweite Vorgehensweise wird als optimistisches Datensatz-Sperren bezeichnet. Sie handhabt das Schreibrecht auf den Datensatz flexibel, und weist es nur zu, wenn der Datensatz aktualisiert werden muss. Beim pessimistischen Sperren wird der Datensatz gesperrt, auch wenn er nicht aktualisiert werden muss. Beim optimistischen Sperren wird die Gültigkeit einer Änderung im Datensatz zum Zeitpunkt der Aktualisierung bestimmt.
ORDA bietet zwei Sperrmodi für Entities:
- einen automatischen "optimistischen" Modus, der für die meisten Anwendungen passt
- einen "pessimistischen" Modus, um Entities zu sperren, bevor darauf zugegriffen wird
Dieser automatische Mechanismus basiert auf dem Konzept "optimistisches Sperren", das sich besonders für Belange von Web Applikationen eignet. Dafür gelten folgende Vorgehensweisen:
- Alle Entities lassen sich immer im Lese-/Schreibmodus laden; es gibt kein vorrangiges Sperren von Entities.
- Jede Entity hat einen internen Sperrstempel, der bei jedem Sichern erhöht wird.
- Versucht ein Benutzer oder Prozess, eine Entity mit der Methode entity.save( ) zu sichern, vergleicht 4D den Wert des Stempels der zu sichernden Entity mit dem der Entity in den Daten (im Falle einer Änderung):
- Stimmen die Werte überein, wird die Entity gesichert und der interne Stempelwert erhöht.
- Stimmen die Werte nicht überein, heißt das, dass zwischenzeitlich ein anderer Benutzer diese Entity geändert hat. Es wird keine Sicherung durchgeführt und ein Fehler zurückgegeben.
Nachfolgendes Diagramm illustriert optimistisches Sperren:
1. Zwei Prozesse laden die gleiche Entity.

2. Der erste Prozess ändert die Entity und bestätigt die Änderung. Die Methode entity.save( ) wird aufgerufen. Die 4D Engine vergleicht automatisch den internen Stempelwert der geänderten Entity mit dem der in den Daten gespeicherten Entity. Da sie zusammenpassen, wird die Entity gesichert und der Stempelwert hochgesetzt.

3. Der zweite Prozess ändert auch die geladene Entity und bestätigt die Änderungen. Die Methode entity.save( ) wird aufgerufen. Da der Stempelwert der geänderten Entity nicht mit der in den Daten gespeicherten Entity übereinstimmt, wird die Sicherung nicht durchgeführt und ein Fehler zurückgegeben.

Das lässt sich auch mit folgendem Code darstellen:
$person1:=ds.Person.get(1)
$person2:=ds.Person.get(1)
$person1.name:="Bill"
$result:=$person1.save()
$person2.name:="William"
$result:=$person2.save()
In diesem Beispiel weisen wir $person1 eine Referenz auf die Entity person mit der Nummer 1 zu. Dann weisen wir der Variablen $person2 eine andere Referenz auf dieselbe Entity zu. In $person1 ändern wir den Vornamen der Person und sichern die Entity. Versuchen wir dasselbe für $person2, prüft 4D, ob die Entity auf der Festplatte die gleiche ist wie die zuerst zugewiesene Referenz in $person1. Da das nicht der Fall ist, gibt 4D in der Eigenschaft success false zurück und sichert die zweite Änderung nicht.
Tritt diese Situation ein, können Sie z.B. die Entity über die Methode entity.reload() erneut von der Festplatte laden und versuchen, die Änderung auszuführen. Die Methode entity.save( ) enthält eine Option "automerge", um die Entity auch dann zu sichern, wenn durch Prozesse andere Attribute geändert wurden.
Hinweis: Datensatzstempel werden nicht in Transaktionen verwendet, da in diesem Zusammenhang nur eine einzige Kopie eines Datensatzes existiert. Unabhängig von der Anzahl der Entities, die einen Datensatz referenzieren, wird dieselbe Kopie geändert, so dass entity.save( ) Operationen niemals Stempelfehler erzeugen.
Sie können Entities bei Zugreifen auf Daten direkt sperren und entsperren. Wird eine Entity von einem Prozess gesperrt, ist sie in diesem Prozess im Lese/Schreibmodus verfügbar und für alle anderen Prozesse gesperrt, d.h. sie können die Entity nur im Lesemodus laden und ihre Werte lassen sich weder bearbeiten noch sichern.
Dieses Feature basiert auf zwei Methoden der Entity Class:
Weitere Informationen dazu finden Sie unter der Beschreibung dieser Methoden.
Verwenden Sie klassische und ORDA Befehle gleichzeitig zum Sperren von Datensätzen, gelten folgende Prinzipien:
- Datensatz´-Sperren mit klassischem 4D Befehl führt dazu, dass ORDA die zum Datensatz passende Entity nicht sperrt.
- Entity-Sperren mit ORDA führt dazu, dass klassische 4D Befehle den zur Entity passenden Datensatz nicht sperren.
Folgende Grafik erläutert diese Prinzipien:

Auch Transaktion-Sperren wird für klassische und ORDA Befehle angewandt. In einer Anwendung mit mehreren Prozessen oder mehreren Benutzern führt Datensatz- Sperren innerhalb einer Transaktion über einen klassischen Befehl dazu, dass andere Prozesse Entities, die mit diesem Datensatz verbunden sind (oder umgekehrt) nicht sperren, bis die Transaktion bestätigt oder abgebrochen wird.
- Beispiel zu Sperren über einen klassischen Befehl:

- Beispiel zu Sperren über eine ORDA Methode:
