Phantomproblem

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

In der Informatik ist das Phantomproblem (inconsistent read) ein Fehler, der bei mehreren parallelen Datenbankzugriffen auftreten kann. Werden während einer Transaktion, die sich auf mehrere Datensätze mit einer angegebenen Eigenschaft bezieht, in einer gleichzeitig ablaufenden Transaktion neue Datensätze mit dieser Eigenschaft eingefügt, kann dies inkonsistente Daten der ersten Transaktion zur Folge haben.

Beispiele für das Phantomproblem

[Bearbeiten | Quelltext bearbeiten]
Über eine komplette Spalte soll eine Verknüpfung berechnet werden

Konkret kann das beispielsweise die Bildung des Mittelwertes einer Spalte sein. Transaktion 1 ermittelt zunächst die Summe über die Spalte in der Tabelle; danach fügt Transaktion 2 einen neuen Datensatz hinzu. Als dritter Schritt berechnet Transaktion 1 die Anzahl der Datensätze über die Spalten. Am Ende wird die vorher ermittelte Summe aller Daten aus unserer Spalte durch die Anzahl der Datensätze geteilt. Problem bei der Berechnung ist nur, dass die Summe der gezählten Datensätze höher ist, da mittendrin ein neuer Datensatz eingefügt wurde. Dadurch wird der Mittelwert verfälscht.

Zeitpunkt Transaktion 1 Transaktion 2
1 SELECT SUM(anzahl) FROM lagerbestand;

Ergebnis: Anzahl Waren im Lager insgesamt, z. B. bei zwei unterschiedlichen Artikeln mit je einem Exemplar der Wert 2.

2 INSERT INTO lagerbestand (artikel, anzahl) VALUES ('Wikipedia: Das Buch', 3);
3 SELECT COUNT(*) FROM lagerbestand;

Ergebnis: Anzahl unterschiedlicher Artikel im Lager. Nach dem parallel laufenden INSERT ist der zurückgegebene Wert 3. Wird das Ergebnis von vorhin durch diesen Wert geteilt, um die durchschnittliche Anzahl von Exemplaren zu ermitteln, wird nicht das korrekte Ergebnis (5/3) errechnet, sondern ein zu niedriger Wert (2/3).

Am einfachsten kann dieses Problem vermieden werden, wenn bei einer für das Phantomproblem anfälligen Transaktion die komplette Tabelle gesperrt wird. Es genügt jedoch, Modifikationen der betroffenen Spalte bei den betroffenen Datensätzen zu verhindern, wenn gleichzeitig sichergestellt werden kann, dass keine neuen Einträge hinzugefügt werden können oder bestehende Einträge entfernt werden können, die ebenfalls später in der Transaktion erfasst würden.

Datenbanken kennen die der Isolationsebene serializable des SQL-Standards entsprechende Möglichkeit der Serialisierung von parallelen Transaktionen. Wird diese Isolationsebene eingesetzt, müssen Anwendungen, die auf die Datenbank zugreifen, mit hierdurch entstehenden, fehlgeschlagenen Zugriffen (Serialisierungsfehlern) umgehen können.

Viele Datenbanken haben die Fähigkeit des wiederholbaren Lesens entsprechend der Isolationsebene repeatable read des SQL-Standards. Das bedeutet, dass bei Änderung eines Datensatzes der Zeitpunkt der Änderung mit abgelegt wird. Eine Transaktion, die vor dieser Änderung begonnen hat, "sieht" die Änderung dann nicht. Dies bezieht sich jedoch oft nicht auf neu angelegte Datensätze, sondern garantiert nur, dass ein erneuter Lesevorgang auf bereits gelesene Daten innerhalb einer Transaktion dasselbe Ergebnis hat.