Zum Inhalt springen

Aufgabe 02 - Isolationsstufen und Fehlerklassen (Ticketshop)

Zu Zen-Modus wechseln

Aufgabe 02 - Isolationsstufen und Fehlerklassen (Ticketshop)

Abschnitt betitelt „Aufgabe 02 - Isolationsstufen und Fehlerklassen (Ticketshop)“

Diese Übung macht die Fehlerklassen paralleler Transaktionen sichtbar und zeigt, wie Isolationsstufen sie unterdrücken (siehe Kapitel 1 - Transaktionen und Parallelität). Szenario ist ein Ticketshop mit begrenzten Restkarten, bei dem zwei Käufer gleichzeitig zugreifen. Im Expertenteil wird ein Serialisierungskonflikt erzeugt und mit einer Wiederholung (Retry) sauber behandelt.

  • Sie ordnen die Fehlerklassen Dirty Read, Non-repeatable Read und Phantom Read korrekt zu.
  • Sie stellen die Isolationsstufe einer Transaktion gezielt ein.
  • Sie reproduzieren ein Non-repeatable Read und zeigen, welche Stufe es verhindert.
  • Sie behandeln einen Serialisierungskonflikt unter SERIALIZABLE mit einer Retry-Strategie.
  • Reproduktion: Fehlerklassen und Isolationsstufen benennen und zuordnen (Teil A).
  • Reorganisation und Transfer: ein Non-repeatable Read reproduzieren und unterdrücken (Teile B und C).
  • Reflexion, Problemlösung und Urteilsbildung: einen Serialisierungskonflikt behandeln und die richtige Stufe begründen (Teil D).

Die Übung ist auf etwa zwei Stunden ausgelegt. Teil D ist der Expertenteil.

CREATE TABLE events (
event_id INT PRIMARY KEY,
titel VARCHAR(60),
restkarten INT NOT NULL CHECK (restkarten >= 0)
);
INSERT INTO events VALUES
(1, 'Robotik-Symposium', 2),
(2, 'Datenbank-Workshop', 10);

Die Isolationsstufe einer Transaktion setzt man direkt nach BEGIN, zum Beispiel:

BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;

Ordnen Sie jeder Beschreibung die passende Fehlerklasse zu (Dirty Read, Non-repeatable Read, Phantom Read) und notieren Sie, ob PostgreSQL diese Klasse in der Standardstufe READ COMMITTED überhaupt zulässt:

  1. Eine Transaktion liest eine Änderung, die eine andere noch nicht bestätigt hat und später zurückrollt.
  2. Eine Transaktion liest dieselbe Zeile zweimal und bekommt verschiedene Werte, weil dazwischen jemand committet hat.
  3. Eine Transaktion führt dieselbe WHERE-Abfrage zweimal aus und bekommt beim zweiten Mal zusätzliche Zeilen.

Unter READ COMMITTED:

  1. S1 startet eine Transaktion und liest restkarten von Event 1.
  2. S2 verkauft eine Karte (UPDATE ... SET restkarten = restkarten - 1) und committet.
  3. S1 liest restkarten von Event 1 erneut — in derselben Transaktion.

Notieren Sie beide gelesenen Werte und benennen Sie die beobachtete Fehlerklasse.

  1. Wiederholen Sie Teil B, diesmal beginnt S1 mit ISOLATION LEVEL REPEATABLE READ.
  2. Welchen Wert liest S1 beim zweiten Mal jetzt? Erklären Sie, warum S1 die zwischenzeitliche, committete Änderung von S2 nicht sieht.

Teil D - Expertenteil: Serialisierungskonflikt und Retry

Abschnitt betitelt „Teil D - Expertenteil: Serialisierungskonflikt und Retry“

Event 1 hat nur noch wenige Restkarten. Zwei Käufer sollen nicht mehr Karten verkaufen, als vorhanden sind.

  1. Konflikt erzeugen: Beide Sitzungen starten mit ISOLATION LEVEL SERIALIZABLE, lesen restkarten und buchen dann eine Karte ab. Führen Sie die Schritte streng von oben nach unten aus und wechseln Sie nach jeder Zeile das Fenster:

    -- S1 -- S2
    BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    SELECT restkarten FROM events WHERE event_id = 1;
    SELECT restkarten FROM events WHERE event_id = 1;
    UPDATE events SET restkarten = restkarten - 1 WHERE event_id = 1;
    UPDATE events SET restkarten = restkarten - 1 WHERE event_id = 1;
    -- S2 blockiert jetzt und wartet auf S1
    COMMIT;
    -- sobald S1 committet, bricht S2s UPDATE ab:
    -- ERROR: could not serialize access
    -- due to concurrent update
    COMMIT; -- beendet nur die schon gescheiterte Transaktion

    Beachten Sie den Zeitpunkt: Der Fehler tritt nicht erst bei S2s COMMIT auf, sondern sobald S1 committet und S2s wartendes UPDATE fortgesetzt wird. Es scheitert immer die Sitzung, die als zweite schreibt (hier S2). Notieren Sie die genaue Fehlermeldung.

    Hinweis: Es gibt hier kein Timing-Problem. S2s UPDATE wird von PostgreSQL blockiert, bis S1 seine Transaktion beendet — die Reihenfolge ist also erzwungen, egal wie schnell Sie tippen. Wichtig ist nur, dass Sie die Zeilen in der gezeigten Reihenfolge ausführen.

  2. Retry: Beschreiben Sie in Worten (oder als Pseudocode), wie eine Anwendung darauf reagieren soll: die gescheiterte Transaktion wiederholen, nicht dem Benutzer einen Fehler zeigen. Warum ist ein Retry hier korrekt und kein „doppelter Verkauf”?

  3. Urteil: Vergleichen Sie zwei Lösungswege für dieses Problem — SERIALIZABLE mit Retry gegen SELECT ... FOR UPDATE unter READ COMMITTED. Nennen Sie je einen Vor- und einen Nachteil.

  1. Nennen Sie die drei klassischen Fehlerklassen paralleler Transaktionen.
  2. Welche Isolationsstufe ist in PostgreSQL die Standardeinstellung, und welche Fehlerklasse lässt sie noch zu?
  3. Was unterscheidet ein Non-repeatable Read von einem Phantom Read?
  4. Was bedeutet die Fehlermeldung „could not serialize access”, und wie reagiert eine Anwendung richtig darauf?
  5. Warum erkauft man höhere Isolation meist mit geringerer Parallelität?
  • Die Datei aufgabe02_isolation.sql mit allen Abfragen und den gesetzten Isolationsstufen.
  • Eine Tabelle mit den in Teil A–C beobachteten Lesewerten und der jeweils benannten Fehlerklasse.

HTL Villach, Schuljahr 2026-2027,
https://www.htl-villach.at