Lade...
 

BeginLock

BeginLock(ACCESS, GRANULARITY)

199820

BeginLock, BeginLock(ACCESS), BeginLock(,GRANULARITY), BeginLock(ACCESS, GRANULARITY)

Stack
Stack Objekttyp
Stack (In) -
Stack (Out) -
 
Beschreibung

Dieser Befehl dient dazu, das Page-Locking von ObjectStore zu steuern. Jedes BeginTXN, das eine Transaktion startet,  setzt das Page-Locking auf (UPGRADABLE, PAGE). Es wird also beim Zugriff auf Objekte die Page der Objekte gelocked. Bei einem Lesezugriff wird die Page dabei nur mit einem Read-Lock versehen, welches bei späteren Schreibzugriffen zu einem Write-Lock werden kann.

Das Locking ist nur innerhalb einer Transaktion definiert, deshalb öffnet BeginLock eine Transaktion, falls noch keine offen war. Dabei wird bei BeginLock(WRITE) immer eine Schreibtransaktion geöffnet, bei BeginLock(UPGRADABLE) hängt die Art der Transaktion vom Modus ab, in welchem die Datenbank geöffnet ist. Der gesetzte Locking-Modus kann mit dem Befehl EndLock wieder in den Zustand vor dem letzten BeginLock gebracht werden. BeginLock und EndLock können dabei beliebig verschachtelt werden. BeginLock arbeitet nicht additiv sondern ersetzt den letzten mit BeginLock gesetzten Locking-Modus vollständig durch den angegebenen Modus. Der gesetzte Locking-Modus ist nur bis zum Transaktionsende gültig. Beim Transaktionsende werden auch alle Locks wieder freigegeben.

Wird der Locking-Modus geändert, dann betrifft dies nur das Locking von Objekten, die vor dem BeginLock noch nicht angefasst wurden. Alle anderen Objekte haben bereits ein entsprechendes Lock, welches erst mit dem Ende der Transaktion wieder freigegeben wird. BeginLock ist auch nicht so zu verstehen, dass der Befehl aktiv eine Page,Segment,Cluster,Datenbank locked, sondern er setzt lediglich das künftige Locking-Verhalten für diese Transaktion.
 

Achtung: BeginLock(WRITE) darf nicht verwendet werden, wenn die Datenbank im MVCC-Modus geöffnet ist, da ansonsten der Zugriff auf persistente Objekte ein Write-Lock anfordern würde, was für MVCC-Datenbanken ein Fehler ist.
Dies Betrifft also BeginTXN(READ)-Transaktionen und reguläre Transaktionen in READ_ONLY-Datenbanken.


Wie im nächsten Abschnitt beschrieben, kann der Write-Lock-Modus dazu verwendet werden, um Deadlocks zu verhindern, jedoch sollte vom exzessiven Gebrauch von Write-Locks abgesehen werden. Falls das gelockte Objekt in der Transaktion gar nicht beschrieben wird, müssen alle anderen Clients trotzdem warten, bis der Client mit dem Lock seine Transaktion beendet hat, um das Objekt zu lesen. Das kann die Performance stark beeinträchtigen und in diesem Fall verhindern die Write-Locks keinen Deadlock.

 

Deadlocks

Dieser Befehl kann dazu verwendet werden, um Deadlocks zu verhindern, die mit dem UPGRADABLE-Lock recht einfach auftreten können. Führen zwei Prozesse genau den gleichen Code aus, dann kann es durch die UPGRADABLE-Locks zu einem Deadlock kommen, denn wenn zwei Prozesse bereits ein Read-Lock für ein Objekt X erhalten haben, dann kann keiner der beiden Prozesse ein Write-Lock für X erhalten, weil hierzu alle anderen Prozesse ihre Read-Locks auf X vorher freigeben müssen (Lock-Regeln). Dieser Ablauf ist in folgendem Diagramm veranschaulicht.

Deadlock-Beispiel
Deadlock-Beispiel

 

Das Verhindern von Deadlocks ist der häufigste Use-Case von BeginLock. In diesem Fall reicht es, vor dem initialien Laden des Objekts den Locking-Modus auf (WRITE, PAGE) (default falls nicht angegeben) zu setzten, damit die Prozesse beim ersten Zugriff versuchen, ein Write-Lock zu erhalten. Der ObjectStore-Server serialisiert die Write-Lock-Anfragen der Prozesse und einer der beiden erhält das Write-Lock, während der andere so lange warten muss, bis die Transaktion des ersten Prozesses beendet ist, damit der zweite sein Write-Lock erhält. Der Deadlock ist hiermit aufgehoben. Dies ist im nächsten Diagramm veranschaulicht.

Deadlock-Auflösung
Deadlock-Auflösung

 

Lock-Regeln

Für das Verständnis von Deadlock-Situationen ist es notwendig zu verstehen, wie sich Read- und Write-Locks verhalten. Im folgenden wird von Locks auf Objekten gesprochen, die kleineste Einheit für die ObjectStore ein Lock vergeben kann sind Pages. Befindet sich ein Objekt mit anderen Objekten auf der gleichen Page, dann wird bei einem Zugriff auf das Objekt die gesamte Page und damit die restlichen Objekte mitgelocked.

Read-Lock: Kann von beliebig vielen Prozessen für das gleiche Objekt gleichzeitig gehalten werden. Ein Read-Lock kann nur dann angefordert werden, wenn es keinen Prozess gibt, der bereits ein Write-Lock auf das Objekt hat. Ansonsten muss gewartet werden, bis der Prozess das Write-Lock freigegeben hat (Transaktionsende). Mit einem Read-Lock darf ein Objekt nur gelesen werden, bei einem Schreibzugriff wird versucht, ein Write-Lock für das Objekt anzufordern.

Write-Lock: Kann nur von einem Prozess zur Zeit für ein Objekt gehalten werden. Hat ein Prozess bereits das einzige Read-Lock auf ein Objekt, dann kann dieses Read-Lock in ein Write-Lock umgewandelt werden. Ein Write-Lock kann nur dann erfolgreich angefordert werden, wenn kein anderer Prozess ein Write- oder Read-Lock auf das Objekt hält. Ansonsten muss gewartet werden, bis die Locks freigegeben werden (Transaktionsende). Mit einem Write-Lock darf auf einem Objekt gelesen und geschrieben werden.

 

ACCESS-Werte
ACCESS Beschreibung
UPGRADABLE Ist der erste Zugriff auf das Objekt lesend, dann wird ein Read-Lock angefordert, welches bei späterem Schreibzugriff zu einem Write-Lock werden kann.
WRITE Default - Beim ersten Lese-/Schreibzugriff auf das Objekt wird direkt ein Write-Lock für das Objekt angefordert.
GRANULARITY-Werte
GRANULARITY Beschreibung
PAGE Default - Wird ein Objekt angefasst, dann wird nur dessen Page gelocked.
CLUSTER Wird ein Objekt angefasst, dann wird dessen gesamter Cluster gelocked.
SEGMENT

Wird ein Objekt angefasst, dann wird dessen gesamtes Segment gelocked.

Use-Case: Batchlauf manipuliert alle Objekte eines Segments und will durch das Locken des Segments sicherstellen, dass keine Clients einzelne Objekte lockend und damit den Batchlauf mittendrin stoppen können.

DATABASE Wird ein Objekt angefasst, dann wird dessen gesamte Datenbank gelocked.

Use-Case: Datenbankwartungstools, die sicherstellen müssen, dass kein anderer Client die Datenbank beschreibt.