Sperrverfahren

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

Sperrverfahren werden in Datenbanksystemen eingesetzt, um die Forderung der Isolation des ACID-Prinzips bei Transaktionen zu erfüllen. Alle Sperrverfahren, auch Sperrprotokolle genannt, fallen in die Kategorie der pessimistischen Synchronisationsverfahren („Pessimistisches Locking“), d. h. es wird bei dem Start einer Transaktion davon ausgegangen, dass es mit hoher Wahrscheinlichkeit zu einem Konflikt mit einer parallel ablaufenden Transaktion kommt. Deren Gegenteil bilden optimistische Verfahren, die Schedules auf Konflikte untersuchen und ggf. eine der beteiligten Transaktionen zurücksetzen („Rollback“).

Einführung[Bearbeiten]

Um eine Transaktion formal darstellen zu können, wird der Vereinfachung halber angenommen, dass auf einem Datenbankobjekt a entweder eine Lese- oder eine Schreiboperation stattfinden kann. Beim Lesen wird das Objekt, im Gegensatz zum Schreiben, nicht verändert.

Um mehrere Transaktionen, welche gleichzeitig auf das gleiche Datenbankobjekt zugreifen wollen, miteinander zu synchronisieren, kann jede Transaktion eine Lesesperre (shared lock) oder eine Schreibsperre (exclusive lock) auf ein Objekt anfordern.

Bevor eine Transaktion T das Objekt a nutzen darf, muss sie eine Sperre für a anfordern (R(a)). Wenn eine andere Transaktion P das gewünschte Objekt allerdings exklusiv gesperrt hat, muss T solange warten, bis P das Objekt wieder freigegeben hat und T die Lesesperre erhält. Während dieser Wartezeit spricht man davon, dass T blockiert ist. Eine Blockade kann immer dann auftreten, wenn eine andere Transaktion bereits eine Sperre auf das gewünschte Objekt a gesetzt hat.

In dem Fall, dass mehrere Transaktionen gegenseitig auf die Freigabe von Sperren warten, das heißt, sie sich gegenseitig blockieren, spricht man von einem „Deadlock“.

In welchen Situationen eine Blockade erfolgt, hängt von dem jeweils eingesetzten Sperrverfahren ab und kann aus der dazugehörenden Kompatibilitätsmatrix (s. u.) abgelesen werden.

formale Schreibweisen[Bearbeiten]

Transaktion T_i liest Objekt a: r_i(a)

Transaktion T_i schreibt Objekt a: w_i(a)

Transaktion T_i fordert eine Lesesperre auf dem Objekt a an: R_i(a)

Transaktion T_i fordert eine Schreibsperre auf dem Objekt a an: X_i(a)

Kompatibilitätsmatrix[Bearbeiten]

Die Kompatibilitätsmatrix gibt an, ob eine Transaktion eine bestimmte Sperre auf ein Objekt erhalten kann, wenn eine andere Transaktion bereits eine Sperre auf demselben Objekt erhalten hat.

R X
R +
X

Leseart:

  • In der obersten Zeile ist die Art der bereits gesetzten Sperre angegeben.
  • In der ersten Spalte ist die Art der von einer anderen Transaktion angeforderten Sperre angegeben.
  • Das "+" sagt aus, dass die angeforderte Sperre zu der bereits gesetzten kompatibel ist und die Sperre somit gesetzt werden kann. Demzufolge wird die anfordernde Transaktion nicht blockiert
  • Das "−" sagt aus, dass die Sperren nicht kompatibel sind und die anfordernde Transaktion blockiert wird.

Fundamentalsatz des Sperrens[Bearbeiten]

Jede Transaktion, welche Sperren nutzt, muss die folgenden Sperrbedingungen einhalten:

  1. Für jedes Objekt, welches von der Transaktion benutzt werden soll, muss vor der Nutzung eine Sperre angefordert werden.
  2. Eine Transaktion darf eine von ihr bereits gesetzte Sperre auf demselben Objekt nicht nochmals anfordern.
  3. Spätestens am Ende der Transaktion (EOT) müssen wieder alle von der Transaktion gesetzten Sperren freigegeben werden.
  4. Jede Transaktion muss die durch andere Transaktionen gesetzten Sperren beachten.
  5. Jede Transaktion durchläuft die Phasen des Wachstums der Sperren und deren Schrumpfung (siehe unten).

Zwei-Phasen-Sperrprotokoll[Bearbeiten]

Varianten von 2PL

Das 2PL-Verfahren (2 Phases Locking) geht davon aus, dass jede Transaktion zwei Phasen durchläuft:

  1. Die Wachstumsphase, in welcher Sperren nur gesetzt, aber nicht freigegeben werden dürfen.
  2. Die Schrumpfungsphase, in welcher Sperren nur freigegeben, aber nicht angefordert werden dürfen.

Dabei wird zwischen zwei Sperren unterschieden:

  1. Read-Lock (auch shared): mehrere Prozesse können lesend auf das gesperrte Objekt zugreifen.
  2. Write-Lock (auch exclusive): nur der sperrende Prozess kann auf das Objekt zugreifen und dieses auch schreiben.

Es gibt zwei Spezialfälle von 2PL:

  1. Das konservative 2-Phasen-Sperrprotokoll (Preclaiming), bei welchem zu Beginn der Transaktion alle benötigten Sperren auf einmal gesetzt werden. Dies verhindert in jedem Fall Deadlocks, führt aber auch zu einem hohen Verlust an Parallelität, da eine Transaktion ihre erste Operation erst dann ausführen kann, wenn sie alle Sperren erhalten hat. Weiterhin muss im Voraus bekannt sein, welche Sperren von der Transaktion benötigt werden, was zumindest bei einer bedingten if-then-else-Anweisung nicht trivial zu lösen ist. Aus diesem Grund wird diese Variante in der Praxis kaum eingesetzt. Es kann bei dieser Variante bereits vor Ende der Transaktion mit der Freigabe gesperrter Objekte begonnen werden.
  2. Das strikte 2-Phasen-Sperrprotokoll, bei welchem alle gesetzten Write-Locks erst am Ende der Transaktion (nach der letzten Operation) freigegeben werden. Dieses Vorgehen verhindert den Schneeballeffekt, also das kaskadierende Zurücksetzen von sich gegenseitig beeinflussenden Transaktionen. Der Nachteil ist, dass Sperren häufig viel länger gehalten werden als nötig und sich somit die Wartezeit von blockierten Transaktionen verlängert. Die Read-Locks werden entsprechend dem Standard-2PL-Verfahren entfernt.

Falls beide Verfahren in Kombination eingesetzt werden, führt dies automatisch dazu, dass alle Transaktionen, die auf das gleiche Objekt zugreifen, sequentiell nacheinander ausgeführt werden. Dies widerspricht der Idee des Transaktionskonzeptes.

Im Folgenden werden Sperrprotokolle vorgestellt, die auf dem 2PL-Verfahren basieren und somit dem Fundamentalsatz des Sperrens gehorchen.

RX-Sperrverfahren[Bearbeiten]

Das RX-Protokoll kennt nur die beiden klassischen Sperren: X (von englisch eXclusive = ausschließlich) als Sperre bei Modifikationen, meist Schreiben, und die S-Sperre (von englisch share = teilen, gemeinsam benutzen), bei der das Objekt unverändert bleibt und die den gleichzeitigen Zugriff zulässt. Da dies für das Lesen zutrifft, wird die S-Sperre häufig auch als R-Sperre (von englisch read = lesen) bezeichnet. Eine Transaktion, die eine Schreibsperre anfordert, muss so lange warten, bis alle Sperren anderer Transaktionen freigegeben wurden.

Während die Schreibsperre gesetzt ist, kann keine andere Transaktion eine weitere Lese- oder Schreibsperre für das Objekt erhalten. Das heißt, eine schreibende Transaktion blockiert sämtliche andere Transaktionen, die dasselbe Objekt benötigen.

RX-Kompatibilitätsmatrix[Bearbeiten]

R X
R +
X

RAX-Kompatibilitätsmatrix[Bearbeiten]

Erweiterung für Lesen mit Absicht zu schreiben (A). Diese Sperrenform bietet viel Durchsatz, wobei die Schreiber verhungern können, wenn immer neue Leser kommen.

R A X
R + +
A +
X

RUX-Kompatibilitätsmatrix[Bearbeiten]

Erweiterung für Lesen mit exklusiver Änderungsabsicht (U). Bei Schreibabsicht wird U in X geändert, nachdem R-Sperren aufgehoben sind. Wird doch nicht geändert, wird die U-Sperre in eine R-Sperre geändert. Es kann nur eine Transaktion eine U-Sperre halten. Schreiber können nicht mehr verhungern. Weniger Durchsatz als bei RAX.

R U X
R +
U +
X

RAC-Kompatibilitätsmatrix[Bearbeiten]

Erweiterung der Parallelität, indem Lesevorgänge besser unterstützt werden. Eine A-Sperre, wenn das Objekt geändert werden soll. Mit Hilfe der C-Sperre werden die beiden Versionen der Kopie konsistent gemacht. Bei gesetzter C-Sperre gibt es zwei Objektversionen, eine vor der beendeten Transaktion mit A-Sperre und eine nach der Transaktion. Je nach Start des Lesevorgangs wird die passende Version ausgewählt.

R A C
R + + +
A +
C +

IX-Kompatibilitätsmatrix[Bearbeiten]

Bei diesem Verfahren werden verschiedene Granulate unterschieden. Grobe Granulate definieren ganze Relationen als gesperrtes Objekt, während feine Granulate nur einzelne Sätze einer Relation betreffen. Intention Read (IR) setzt eine Sperre auf einer feinen Granularitätsstufe. Intention eXclusive (IX) ist die passende Sperre für das Schreiben auf feinerer Granularitätsstufe.

IR IX R X
IR + + +
IX + +
R + +
X

RIX-Kompatibilitätsmatrix[Bearbeiten]

Dieses Verfahren ist eine weitere Verfeinerung der IX-Sperre. RIX setzt sich zusammen aus R (Read) + IX (Intention eXclusive). RIX kann verwendet werden für den Fall, dass alle Sätze eines Satztyps gelesen, aber nur einige geändert werden sollen. In diesem Fall wäre eine X-Sperre auf den Satztyp zu restriktiv und eine IX-Sperre würde das Sperren jedes Satzes verlangen. RIX sperrt das Objekt im R-Modus und verlangt X-Sperren auf tieferen Hierarchieebenen nur für zu ändernde Objekte.

IR IX R RIX U X
IR + + + +
IX + +
R + +
RIX +
U +
X
In diesem Artikel oder Abschnitt fehlen folgende wichtige Informationen:
  • U-Sperre
  • IS-Sperre
  • SIX-Sperre

Du kannst Wikipedia helfen, indem du sie recherchierst und einfügst, aber kopiere bitte keine fremden Texte in diesen Artikel.

Multiversion Concurrency Control (MVCC)[Bearbeiten]

Hauptartikel Multiversion Concurrency Control.

Siehe auch[Bearbeiten]

Literatur[Bearbeiten]

  • R. Elmasri et al: Grundlagen von Datenbanksystemen. Pearson Studium, 2002, 3ed, ISBN 3-8273-7021-3, S. 714 ff.

Weblinks[Bearbeiten]