Die Serialisierbarkeitstheorie spielt eine zentrale Rolle im Bereich der Datenbanksysteme und stellt sicher, dass mehrere gleichzeitig ablaufende Transaktionen das System nicht in einen inkonsistenten Zustand versetzen. In einer Welt, in der Anwendungen zunehmend parallel und verteilt arbeiten, ist das Management von Transaktionen von entscheidender Bedeutung. Die Theorie der Serialisierbarkeit bietet dabei eine formale Grundlage, um zu verstehen, wann und wie Transaktionspläne so ausgeführt werden können, dass sie das gleiche Ergebnis liefern wie eine zeitlich nacheinander ablaufende Serie von Operationen. Diese Eigenschaft ist essenziell für die Korrektheit von Datenbanken und die Vermeidung von Fehlern, die durch konkurrierende Zugriffe auftreten können. Grundsätzlich beschreibt eine serialisierbare Historie einen Ablauf von Transaktionen, der äquivalent zu einer seriellen Reihenfolge ist.
Das bedeutet, dass die Auswirkungen dieses konkurrierenden Transaktionsplans denjenigen entsprechen, die entstehen würden, wenn die Transaktionen strikt nacheinander abgearbeitet würden. Diese Äquivalenz ist entscheidend, weil sie sicherstellt, dass die Datenbank immer in einem konsistenten Zustand verbleibt, selbst wenn die Transaktionen parallel laufen. Zur Veranschaulichung kann man sich zwei Transaktionen vorstellen, T1 und T2. Die beiden möglichen seriellen Ausführungsreihenfolgen wären entweder T1 gefolgt von T2 oder T2 gefolgt von T1. Jede parallele Ausführung, die mit einem dieser beiden seriellen Verläufe gleichwertig ist, gilt als serialisierbar.
Ein Beispiel dafür wäre eine Abfolge von Operationen, bei der T2 zuerst einen Wert auf einer Datenbankvariable schreibt, daraufhin T1 denselben Wert liest, und die Ergebnisse am Ende die gleichen sind, als ob T2 vollständig vor T1 ausgeführt worden wäre. Ein zentrales Konzept zur Bestimmung der Serialisierbarkeit ist der sogenannte Serialisierbarkeitsgraph, auch Konfliktgraph genannt. Dieser Graph bildet die Konflikte zwischen Transaktionen ab, die durch widersprüchliche Operationen wie Lesen und Schreiben derselben Daten entstehen. Die Knoten im Graphen repräsentieren die einzelnen Transaktionen, während die gerichteten Kanten eine Abhängigkeit anzeigen. Eine Kante von T1 nach T2 zeigt an, dass T2 auf eine Operation von T1 folgt, mit der ein Konflikt besteht.
Das grundlegende Theorem lautet, dass eine Historie genau dann serialisierbar ist, wenn der Serialisierbarkeitsgraph keinen Zyklus enthält. Ein zyklusfreier Konfliktgraph bedeutet, dass eine lineare Reihenfolge existiert, die den parallelen Ablauf korrekt repräsentiert. Allerdings ist Serialisierbarkeit nicht gleichbedeutend mit absoluter Sicherheit bei der Ausführung der Transaktionen. Eine beliebte Eigenschaft, die man sich zusätzlich wünscht, ist die Recoverability. Diese stellt sicher, dass keine Transaktion eine Änderung einer anderen Transaktion liest, die später noch zurückgerollt wird.
Fehlt diese Eigenschaft, können sogenannte Dirty Reads auftreten, bei denen eine Transaktion Daten liest, die sich im Falle eines Abbruchs als ungültig herausstellen. Dies kann zu Inkonsistenzen führen und die Integrität der Daten gefährden. Ein damit verbundenes Problem sind Kaskadierende Abbrüche. Diese entstehen, wenn eine Transaktion von den Änderungen einer anderen abhängt, die abbricht. In solchen Fällen muss nicht nur die erste Transaktion zurückgerollt werden, sondern auch alle abhängigen Transaktionen, was den Prozess komplex und ineffizient macht.
Daher werden strenge Formen der Serialisierbarkeit angestrebt, die solche Situationen vermeiden. Eine besonders wichtige Klasse von Serialisierbarkeitsrichtungen ist die Konfliktserialisierbarkeit. Dabei richtet sich die Analyse ausschließlich auf Konfliktoperationen wie Schreib-Lese, Lese-Schreib und Schreib-Schreib. Konfliktserialisierbarkeit ist leichter zu erkennen und zu implementieren und bietet dennoch eine solide Garantie für die Korrektheit von Transaktionsplänen. Sie richtet sich auf den bereits erwähnten Serialisierbarkeitsgraph und überprüft die Zyklizität für diese spezifischen Konflikte.
Um praktikable Systeme zu implementieren, die serialisierbare Zeitpläne garantieren, werden oft Kontrollmechanismen wie das Zwei-Phasen-Sperrverfahren (2PL) verwendet. Dieses Verfahren unterteilt den Lebenszyklus einer Transaktion in eine Wachstumsphase, während der alle notwendigen Sperren akquiriert werden, und eine Schrumpfungsphase, in der Sperren sukzessive freigegeben werden. Ein zentrales Merkmal von 2PL ist, dass nach der Freigabe der ersten Sperre keine neuen Sperren mehr erworben werden können. Dieses Verfahren garantiert Konfliktserialisierbarkeit und kann darüber hinaus Strictness sicherstellen. Strictness ist eine weitere wichtige Eigenschaft, die beschreibt, dass eine Transaktion nur dann eine sperrbezogene Operation auf einem Datenobjekt durchführen darf, wenn alle anderen Transaktionen, die auf demselben Objekt Konfliktbeherrschung beanspruchen, bereits abgeschlossen sind – also committet oder abgebrochen wurden.
Dadurch werden kaskadierende Abbrüche vermieden, da Lesetransaktionen keine ungesicherten, eventuell rückgängig gemachten Änderungen einsehen. Strict 2PL ist eine Variante des Zwei-Phasen-Sperrverfahrens, die genau diese Anforderung erfüllt. Die Herausforderung bei der Anwendung von Serialisierbarkeit liegt darin, eine Balance zwischen Systemperformance und Korrektheit zu finden. Strenge Isolation, wie strikte Serialisierbarkeit, kann die Systemleistung aufgrund umfangreicher Wartezeiten und Sperrvergabe einschränken. Andererseits schafft mangelnde Isolierung Raum für Inkonsistenzen und Fehler, die unter Umständen fatale Folgen haben können.
Aus diesem Grund wurden zahlreiche Varianten und Optimierungen entwickelt, die unterschiedliche Grade der Isolation abdecken. Diese werden häufig unter den Begriffen Isolation Levels in Datenbanksystemen zusammengefasst. Grundlegende Isolationlevels wie Read Uncommitted erlauben das Lesen nicht abgeschlossener Transaktionen und sind somit nicht serialisierbar. Levels wie Read Committed verhindern Dirty Reads, erlauben aber dennoch sogenannte Non-Repeatable Reads oder Phantom Reads. Repeatable Read als nächsthöheres Level sorgt dafür, dass die Daten während der gesamten Transaktion unverändert bleiben, vermindert jedoch nicht alle Arten von Anomalien.
Die höchste Isolationsebene, Serializable, garantiert vollständige Serialisierbarkeit und somit den größtmöglichen Schutz vor Problemen konkurrierender Transaktionen. Moderne Datenbanksysteme implementieren oft optimistische oder pessimistische Sperrmechanismen, um Serialisierbarkeit und Deadlock-Vermeidung zu gewährleisten. Optimistische Verfahren gehen davon aus, dass Konflikte selten auftreten, und überprüfen beim Commit Zeitpläne, um mögliche Serialisierbarkeitsverletzungen zu erkennen. Pessimistische Techniken, wie das erwähnte 2PL, sperren Datenobjekte frühzeitig, um Konflikte von vornherein auszuschließen. Neben den theoretischen Aspekten der Serialisierbarkeit sind auch praktische Probleme wie Deadlocks von Bedeutung.