Isolationslevel sind ein zentrales Konzept in der Transaktionsverwaltung von Datenbanken. Sie steuern, wie Transaktionen voneinander isoliert werden und verhindern, dass Änderungen, die eine Transaktion an den Daten vornimmt, andere Transaktionen beeinflussen, bevor sie abgeschlossen ist.
Ein Dirty Read tritt auf, wenn eine Transaktion Daten liest, die von einer anderen Transaktion geändert wurden, die jedoch noch nicht abgeschlossen ist. Sollte die ursprüngliche Transaktion ein Rollback ausführen, würde der zweite Transaktion falsche (oder „schmutzige“) Daten enthalten. Dirty Reads entstehen im Isolationslevel Read Uncommitted, da hier keine Kontrolle darüber besteht, ob die gelesenen Daten commit-fähig sind.
Ein Non-Repeatable Read tritt auf, wenn eine Transaktion denselben Datensatz mehrmals liest und dabei unterschiedliche Werte erhält. Das passiert, wenn eine andere Transaktion die Daten zwischen den Lesezugriffen ändert und committet. Non-Repeatable Reads werden durch das Isolationslevel Repeatable Read verhindert, aber nicht durch Read Committed.
Ein Phantom Read tritt auf, wenn eine Transaktion eine Reihe von Datensätzen liest und eine andere Transaktion in der Zwischenzeit neue Datensätze hinzufügt oder entfernt, die die Ergebnismenge der ersten Transaktion verändern würden. Phantom Reads werden nur im höchsten Isolationslevel Serializable vollständig verhindert. Bei Phantom Reads geht es um die Konsistenz der Ergebnismenge und nicht um einzelne Datensätze.
In einem Datenbankumfeld können mehrere Benutzer oder Prozesse gleichzeitig auf die Datenbank zugreifen und Änderungen vornehmen. Ohne eine Regelung, wie diese gleichzeitigen Zugriffe abgewickelt werden, könnten Daten inkonsistent werden. Hier greifen Isolationslevel ein. Sie legen fest, in welchem Maße Transaktionen unabhängig voneinander arbeiten können, und verhindern verschiedene Arten von Konflikten wie Dirty Reads, Non-Repeatable Reads und Phantom Reads. Die vier gängigen Isolationslevel sind Read Uncommitted, Read Committed, Repeatable Read und Serializable.
Im Isolationslevel Read Uncommitted kann eine Transaktion die Änderungen einer anderen Transaktion sehen, selbst wenn diese noch nicht abgeschlossen ist. Dieses Level bietet die niedrigste Isolation und die höchste Performance, eignet sich jedoch nur in Situationen, in denen Datenkonsistenz weniger kritisch ist.
Beispiel für ein Dirty Read in Read Uncommitted:
-- Transaktion A beginnt und ändert den Wert
BEGIN;
UPDATE konto SET balance = balance - 100 WHERE id = 1;
-- Transaktion B kann den neuen Wert bereits lesen, obwohl Transaktion A noch nicht abgeschlossen ist
SELECT balance FROM konto WHERE id = 1;
-- Transaktion A wird zurückgesetzt (Rollback)
ROLLBACK;
In diesem Beispiel sieht Transaktion B eine Änderung, die am Ende zurückgesetzt wird. Die gelesenen Daten waren also inkonsistent.
Read Committed ist das Standard-Isolationslevel in vielen Datenbanksystemen wie PostgreSQL und SQL Server. Hier kann eine Transaktion nur abgeschlossene (committed) Änderungen anderer Transaktionen lesen. Dadurch werden Dirty Reads verhindert. Allerdings sind Non-Repeatable Reads weiterhin möglich, da Werte sich zwischen zwei Lesezugriffen ändern können, wenn eine andere Transaktion sie modifiziert.
Beispiel für Non-Repeatable Reads in Read Committed:
-- Transaktion A liest den Wert
BEGIN;
SELECT balance FROM konto WHERE id = 1;
-- Transaktion B ändert den Wert und committet
BEGIN;
UPDATE konto SET balance = balance + 100 WHERE id = 1;
COMMIT;
-- Transaktion A liest erneut, sieht aber nun einen geänderten Wert
SELECT balance FROM konto WHERE id = 1;
COMMIT;
Transaktion A liest denselben Datensatz zweimal und sieht unterschiedliche Werte, da Transaktion B den Wert in der Zwischenzeit geändert hat.
Im Isolationslevel Repeatable Read bleiben alle gelesenen Daten über die gesamte Dauer der Transaktion konsistent. Wenn eine Transaktion in Repeatable Read läuft, sieht sie denselben Wert jedes Mal, wenn sie eine bestimmte Zeile liest. Non-Repeatable Reads werden dadurch verhindert, allerdings können Phantom Reads auftreten. Phantom Reads bedeuten, dass neue Datensätze in die Ergebnismenge einfließen können, wenn eine andere Transaktion Datensätze hinzufügt.
Beispiel für Phantom Reads in Repeatable Read:
-- Transaktion A beginnt und liest alle Einträge
BEGIN;
SELECT * FROM konto WHERE balance > 500;
-- Transaktion B fügt einen neuen Eintrag hinzu und committet
BEGIN;
INSERT INTO konto (id, balance) VALUES (3, 700);
COMMIT;
-- Transaktion A führt dieselbe Abfrage erneut aus und sieht nun zusätzliche Ergebnisse
SELECT * FROM konto WHERE balance > 500;
COMMIT;
Hier sieht Transaktion A einen neuen Datensatz bei der zweiten Abfrage, der bei der ersten Abfrage nicht vorhanden war.
Serializable ist das strengste Isolationslevel und verhindert alle Konflikte, einschließlich Phantom Reads. Dieses Level behandelt Transaktionen so, als ob sie nacheinander und nicht gleichzeitig ablaufen würden. Zwar gewährleistet Serializable die höchste Datenkonsistenz, es kann jedoch zu Performance-Einbußen kommen, da Transaktionen möglicherweise warten müssen, um Konflikte zu vermeiden.
Beispiel für vollständige Isolation in Serializable:
-- Transaktion A beginnt und liest alle Einträge
BEGIN;
SELECT * FROM konto WHERE balance > 500;
-- Transaktion B versucht, einen neuen Eintrag hinzuzufügen, aber Transaktion A blockiert dies
BEGIN;
INSERT INTO konto (id, balance) VALUES (4, 700);
-- Transaktion B muss warten, bis Transaktion A abgeschlossen ist
In diesem Fall verhindert das Serializable-Isolationslevel, dass Transaktion B Änderungen vornimmt, bevor Transaktion A abgeschlossen ist. Dadurch sind Phantom Reads ausgeschlossen, und die Transaktionen laufen in vollständiger Isolation.
Die Wahl des Isolationslevels hängt von den Anforderungen an Konsistenz und Performance ab. Read Uncommitted bietet die beste Performance, ist jedoch anfällig für Dateninkonsistenzen. Read Committed ist ein guter Kompromiss und oft der Standard, da es viele Konflikte verhindert und gleichzeitig akzeptable Performance bietet. Repeatable Read und Serializable sind empfehlenswert, wenn absolute Konsistenz erforderlich ist, wobei Serializable bei Transaktionen mit hoher Konfliktgefahr die beste Wahl ist.
In PostgreSQL können Isolationslevel für Transaktionen festgelegt werden, um die gewünschten Konsistenz- und Performance-Anforderungen zu erfüllen. Die Datenbank bietet standardmäßig vier Isolationslevel: Read Uncommitted, Read Committed (Standard), Repeatable Read und Serializable. Diese können auf der Ebene der gesamten Sitzung oder für einzelne Transaktionen konfiguriert werden.
Um den Standard-Isolationslevel in PostgreSQL für alle Transaktionen in einer Sitzung festzulegen, kann der default_transaction_isolation
-Parameter in der PostgreSQL-Konfigurationsdatei postgresql.conf
geändert werden:
# In der Konfigurationsdatei postgresql.conf
default_transaction_isolation = 'repeatable read'
Nachdem die Änderung gespeichert wurde, muss der PostgreSQL-Server neu gestartet werden, damit die Einstellung wirksam wird. Diese Einstellung wirkt sich auf alle neuen Transaktionen aus, die ohne spezifizierten Isolationslevel gestartet werden.
# PostgreSQL-Server neu starten
sudo systemctl restart postgresql
Um den Isolationslevel nur für die aktuelle Sitzung zu ändern, kann der folgende SQL-Befehl ausgeführt werden:
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Alle Transaktionen innerhalb dieser Sitzung werden im angegebenen Isolationslevel ausgeführt, sofern für die Transaktionen kein anderer Level festgelegt wird.
Um den Isolationslevel für eine einzelne Transaktion festzulegen, kann der SET TRANSACTION
-Befehl innerhalb einer Transaktion verwendet werden. So lässt sich der Isolationslevel nur für die Dauer dieser spezifischen Transaktion ändern, was in Anwendungen praktisch ist, in denen unterschiedliche Konsistenzanforderungen bestehen.
BEGIN;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- Transaktionslogik hier
COMMIT;
Im obigen Beispiel läuft die Transaktion im höchsten Isolationslevel Serializable, wodurch alle Konflikte wie Dirty Reads, Non-Repeatable Reads und Phantom Reads verhindert werden.
Read Uncommitted wird in PostgreSQL als Read Committed behandelt, da PostgreSQL Dirty Reads standardmäßig blockiert.
Read Committed ist der Standard-Isolationslevel und verhindert Dirty Reads, erlaubt jedoch Non-Repeatable Reads und Phantom Reads.
Repeatable Read verhindert sowohl Dirty als auch Non-Repeatable Reads, jedoch nicht Phantom Reads.
Serializable bietet den höchsten Grad an Isolation und verhindert alle Konflikte, indem Transaktionen so behandelt werden, als ob sie nacheinander ablaufen.
Die Wahl des Isolationslevels in PostgreSQL kann durch die oben genannten Befehle flexibel an die Anforderungen der jeweiligen Anwendung angepasst werden. Es ist empfehlenswert, die Transaktionsanforderungen gründlich zu evaluieren, um das optimale Gleichgewicht zwischen Konsistenz und Performance zu erreichen.
Finden Sie interessante und zum Thema passende Kurse
In diesem Seminar lernen Sie, was Container sind, wie Sie sie erstellen und verwalten und wie Sie Docker in Ihren Projekten nutzen können. Ziel ist es, Docker von Grund auf zu verstehen und in realen Projekten anwenden zu können.
2 Tage Vollzeit Online
Nächster Termin: 16. Dezember 2024
Preis pro Person: 900,00 EUR
Rabattaktion: 3 für den Preis von 2!
Dieses dreitägige SQL-Seminar vermittelt Anfängern die Grundlagen relationaler Datenbanken anhand von SQLite. Die ersten beiden Tage konzentrieren sich auf Datenbankdesign, Normalisierung, grundlegende SQL-Abfragen sowie Datenmanipulation mit INSERT, UPDATE und ER-Diagrammen. Am dritten Tag werden SQLAlchemy, Migrationen und ORM-Konzepte behandelt, einschließlich Benutzerrechte und grundlegender Optimierungstechniken.
3 Tage Vollzeit auch als Feierabendkurs Online
Nächster Termin: 10. Februar 2025
Preis pro Person: 1600,00 EUR
Rabattaktion: 3 für den Preis von 2!