Concurrency Control

Historie muss mindestens konfliktserialisierbar sein - meistens auch strikt.

Sperrbasierte Synchronisation

Verträglichkeits- / Kompatibilitäts-Matrix

NLNL no lock

SS shared - read lock

XX exclusive - write lock


Bei MGL

ISIS intention shared lock - tiefer in Hierarchie

IXIX intention exclusive lock - tiefer in Hierarchie

2PLs

Zwei-Phasen-Sperrprotokoll 2PL

  1. Jedes Objekt muss vor der Verwendung locked werden
  1. Es darf nicht ein lock angefordert werden, wenn man sie bereits besitzt
  1. locks werden nach Kompatibilitätsmatrix gewährt wenn man nicht blockiert ist
  1. Nach einem unlock, ist kein Anfordern von locks erlaubt (2 Phasen)

    Wachstumsphase → Schrumpfungsphase

  1. BeiEOT\small \tt EOTmüssen alle Sperren freigegeben werden

erzeugt konfliktserialisierbare Historien (ohneabort\small \tt abortseriell)

Strict 2PL

  1. Alle unlocks müssen bisEOT\small \tt EOTblockiert und dann aufeinmal ausgeführt werden.

erzeugt strikte Historien

Conservative 2PL (= Preclaiming)

  1. Alle unlocks müssen bisEOT\small \tt EOTblockiert und dann aufeinmal ausgeführt werden.
  1. Alle locks müssen beiBOT\small \tt BOTaufeinmal ausgeführt werden.

Variante von strict 2PL

Transaktionen nur gestartet wenn sie alle ihre locks von Anfang an bekommen

Vermeidet deadlocks

Deadlocks

Bei 2PLs sind deadlocks möglich.

Sie lassen sich mit conservative 2PL oder Zeitstempelverfahren vermeiden.

  • Beispiel

Erkennung

Time-out Strategie

Einfache Methode

abort\small \tt abort innerhalb einer Zeitspanne keine Fortschritte gemacht werden

timeout zu klein - unnötige abort\small \tt abort s

timeout zu groß - deadlocks zu spät erkannt

Wartegraph

Exakte Methode

gerichtete Kante TiTj\small T_{i} \rightarrow T_{j} falls Ti\small T_{i} auf Tj\small T_{j} wartet.

Deadlock = Zyklus um Graph

Knoten entfernen um Zyklus aufzulösen

Zeitstempelverfahren

Jede Transaktion hat Zeitstempel TS(Ti)\small TS(T_i) zB vergangene Sekunden oder counter

Jüngere Transaktionen = größere Zeitstempel

TS(Ti)<TS(Tj)\small T S\left(T_{i}\right)<T S\left(T_{j}\right)Ti\small T_i älter als Tj\small T_j


Zeitstempel entscheidet ob Transaktion auf lock wartet oder abort\small \tt abort ed wird.

Angenommen T1\small T_1 will lock den T2\small T_2 besitzt.

wound-wait Strategie: ältere Transaktion (kleinere Zahl) setzt sich durch

  1. Wenn T1\small T_1 älter T2\small T_2 wird abort\small \tt abort ed
  1. Wenn T2\small T_2 älter T1\small T_1 wartet bis Freigabe

wait-die Strategie: jüngere Transaktion (größere Zahl) setzt sich durch

  1. Wenn T1\small T_1 älter T2\small T_2 wartet bis Freigabe
  1. Wenn T2\small T_2 älter T1\small T_1 wird abort\small \tt abort ed

Granularität von Sperren

Multiple Granularity Locking (MGL)

kleinere Sperrgranulate → verbesserte Effizienz:

Datensatz \sube Tabelle \sube Seite \sube Segment / area (logisch zusammengehörende pages) \sube Datenbasis

Anforderung: bei lock müssen Kinder auch gelocked werden

Freigabe: nur möglich wenn Kinder auch freigegeben wurden


Delete - X\small X -lock

Andere Transaktionen die ein lock für das Objekt wollen, werden es nach dem commit\small \tt commit der Transaktion nicht mehr erhalten.

Insert - X\small X -lock

Sollte vermieden werden:

Phantomproblem (Indexbereich sperren).

Konfliktserialisierbar ⇏\not \Rarr serialisierbar bei Inserts.

Zeitstempel-basierende Synchronisation

keine Deadlocks

erzeugt konfliktserialisierbare Historie (deshalb kein abort\small \tt abort erlaubt)

Vor jedem Zugriff timestamp abfragen - sich bei Konflikt abort\small \tt abort en.

Umabort\small \tt abortzu ermöglichen

Rücksetzbare Historie

commit\small \tt commit blockieren bis alle Transaktionen von denen gelesen wurde beendet sind.

Strikte Historie

  1. alle Schreib-Operationen am Ende atomar ausführen.
  1. Dirty-bit

    true = Datensatz von aktiver Transaktion geschrieben

    kein kaskadierendes Rücksetzen: Schreiben für andere blockieren wenn true .

    strikte Historie: Schreiben und Lesen für andere blockieren wenn true .

    Nach commit\small \tt commit die dirty-bits auf false setzen.

    Nach abort\small \tt abort - wenn die Transaktion davor commit\small \tt commit ed hat - die dirty-bits aktualisieren und writeTS(A)\small \tt writeTS(\text A) zurücksetzen.

Definition

Jede Transaktion hat timestamp TS(Ti)\small TS(T_i) zB vergangene Sekunden oder counter

Jüngere Transaktionen = größere Zeitstempel

TS(Ti)<TS(Tj)\small T S\left(T_{i}\right)<T S\left(T_{j}\right)Ti\small T_i älter als Tj\small T_j

Jedes Datenobjekt A\small A hat 2 timestamps zum abfragen:

readTS(A)\small \tt readTS(\text A) TS der jüngsten Transaktion die A\small A gelesen hat

writeTS(A)\small \tt writeTS(\text A) TS der jüngsten Transaktion die A\small A geschrieben hat

Lesezugriffri(A)r_i(A)

TS(Ti)<writeTS(A)\small T S\left(T_{i}\right)< \tt writeTS(\text A)

Ti\small T_i ist älter als anderer der geschrieben hat.

Das bedeutet der ursprünglichen Reihenfolge der Transaktionen zufolge, müsste Ti\small T_ivor der Schreiboperation gelesen haben. - Das trifft nicht zu.

Ti\small T_i wird zurückgesetzt.

TS(Ti)writeTS(A)\small T S\left(T_{i}\right) \geq \tt writeTS(\text A)

Ti\small T_i ist jünger oder gleich alt wie anderer der geschrieben hat.

Das bedeutet der ursprünglichen Reihenfolge der Transaktionen zufolge, müsste Ti\small T_inach der Schreiboperation gelesen haben. - Das trifft zu.

Ti\small T_i darf lesen.

readTS(A)=\small \tt readTS(\text A) =~max(TS(Ti),readTS(A)) \small \textcolor{grey}{ \max(}~TS(T_i),~ \small \tt readTS(\text A)~\textcolor{grey}{ )} 

Schreibzugriffwi(A)w_i(A)

TS(Ti)<writeTS(A)\small T S\left(T_{i}\right)< \tt writeTS(\text A)

Ti\small T_i ist älter als anderer der geschrieben hat.

Das bedeutet der ursprünglichen Reihenfolge der Transaktionen zufolge, müsste Ti\small T_ivor der Schreiboperation geschrieben haben. - Das trifft nicht zu.

Ti\small T_i wird zurückgesetzt.

TS(Ti)<readTS(A)\small T S\left(T_{i}\right)< \tt readTS(\text A)

Ti\small T_i ist älter als anderer der gelesen hat.

Das bedeutet der ursprünglichen Reihenfolge der Transaktionen zufolge, müsste Ti\small T_ivor der Leseoperation geschrieben haben, damit die andere Transaktion diesen Wert liest. - Das trifft nicht zu.

Ti\small T_i wird zurückgesetzt.

TS(Ti)writeTS(A)\small T S\left(T_{i}\right) \geq \tt writeTS(\text A)undTS(Ti)readTS(A)\small T S\left(T_{i}\right) \geq \tt readTS(\text A)

Ti\small T_i ist jünger oder gleich alt wie anderer der geschrieben oder gelesen hat.

Ti\small T_i darf schreiben.

writeTS(A)=\small \tt writeTS(\text A) =~TS(Ti)\small TS(T_i)

Transaktionsverwaltung mit SQL

SET TRANSACTION
[ READ WRITE | READ ONLY ]
[ ISOLATION LEVEL {
READ UNCOMMITED | READ COMMMITED | REPEATABLE READ | SERIALIZABLE
}]

READ UNCOMMITED

Schwächste Stufe.

Nicht festgeschriebene, inkonsistente Änderungen können gelesen werden.

Nur für READ ONLY erlaubt.

READ COMMITED

Nur Daten können gesehen werden die vor der Operation commited waren.

REPEATABLE READ

Nur Daten können gesehen werden die vor der Transaktion commited waren.

SERIALIZABLE

Höchste Stufe.