Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.0 (Deutsch) » SQL Anywhere Server - SQL-Benutzerhandbuch » Transaktionen und Isolationsstufen verwenden » Praktische Einführung in Isolationsstufen

 

Praktische Einführung: Dirty Reads

Die folgende praktische Einführung zeigt einen Typ von Inkonsistenz, der auftreten kann, wenn mehrere Transaktionen gleichzeitig ausgeführt werden. Zwei Angestellte einer kleinen Handelsfirma greifen gleichzeitig auf die Datenbank der Firma zu. Bei der ersten Person handelt es sich um den "Sales Manager"(Verkaufsleiter) der Firma. Die zweite Person ist der "Accountant"(Buchhalter).

Der "Sales Manager" möchte den Preis für ein von der Firma verkauftes T-Shirtmodell um $0.95 erhöhen, hat aber Schwierigkeiten mit der Syntax der SQL-Sprache. Was der "Sales Manager" nicht weiß, ist, dass der "Accountant" gleichzeitig versucht, den Einzelhandelswert des gegenwärtigen Inventars für einen Bericht zu berechnen, den er bei der nächsten Besprechung der Geschäftsleitung vorlegen möchte.

Tipp

Vor dem Ändern der Datenbank auf die im Folgenden dargestellte Weise, empfiehlt es sich, die Änderung durch die Verwendung von SELECT anstelle von UPDATE zu testen.

Hinweis

Damit diese praktische Einführung funktioniert, darf die Option Datenbanksperren automatisch freigeben in Interactive SQL (Extras » Optionen » SQL Anywhere) nicht aktiviert sein.

In diesem Beispiel spielen Sie die Rolle von zwei Mitarbeitern, die die SQL Anywhere-Beispieldatenbank gleichzeitig benutzen.

  1. Starten Sie Interactive SQL.

  2. Im Fenster Verbinden stellen Sie als "Sales Manager" eine Verbindung mit der SQL Anywhere-Beispieldatenbank her.

    • Wählen Sie in der Dropdown-Liste Aktion die Option Mit einer ODBC-Datenquelle verbinden.

    • Im Feld ODBC-Datenquellenname wählen Sie SQL Anywhere 12 Demo.

    • Klicken Sie auf Erweitert, um die Registerkarte Erweiterte Optionen anzuzeigen.

    • Klicken Sie auf die Registerkarte Erweiterte Optionen und geben Sie Sales Manager in das Feld ConnectionName ein.

    • Klicken Sie auf Verbinden.

  3. Starten Sie eine zweite Instanz von Interactive SQL.

  4. Im Fenster Verbinden stellen Sie als "Accountant" eine Verbindung mit der SQL Anywhere-Beispieldatenbank her.

    • Wählen Sie in der Dropdown-Liste Aktion die Option Mit einer ODBC-Datenquelle verbinden.

    • Im Feld ODBC-Datenquellenname wählen Sie SQL Anywhere 12 Demo.

    • Klicken Sie, falls erforderlich, auf Erweitert, um die Registerkarte Erweiterte Optionen einzublenden.

    • Klicken Sie auf die Registerkarte Erweitert und geben Sie Accountant in das Feld ConnectionName ein.

    • Klicken Sie auf Verbinden.

  5. Erhöhen Sie als "Sales Manager" die Preise aller T-Shirts um $0.95:

    • Im Fenster Sales Manager führen Sie die folgenden Befehle aus:

      UPDATE Products
         SET UnitPrice = UnitPrice + 95
         WHERE Name = 'Tee Shirt';
      SELECT ID, Name, UnitPrice
         FROM Products;

    Das Ergebnis sieht folgendermaßen aus:

    ID Name UnitPrice
    300 Tee Shirt 104.00
    301 Tee Shirt 109.00
    302 Tee Shirt 109.00
    400 Baseball Cap 9.00
    ... ... ...

    Sie stellen sofort fest, dass Sie 0.95 statt 95 hätten eingeben sollen, aber bevor Sie Ihren Fehler korrigieren können, greift der "Accountant" von einem anderen Büro aus auf die Datenbank zu.

  6. Der "Accountant" der Firma ist besorgt, dass zuviel Geld im Lager steckt. Führen Sie als "Accountant" folgende Befehle aus, um den Gesamt-Einzelhandelswert des Lagerbestandes zu berechnen:

    SELECT SUM( Quantity * UnitPrice )
     AS Inventory
       FROM Products;

    Das Ergebnis sieht folgendermaßen aus:

    Inventory
    21453.00

    Leider ist diese Berechnung falsch. Der "Sales Manager" hat irrtümlich den Preis für die T-Shirts um $ 95 erhöht und das Ergebnis spiegelt diesen fehlerhaften Preis wider. Dieser Fehler zeigt eine typische Art von Inkonsistenz auf, die als Dirty Read bekannt ist. Sie haben als "Accountant" auf Daten zugegriffen, die der "Sales Manager" eingegeben, aber noch nicht festgeschrieben hat.

    Eine Beschreibung, wie Sie Dirty Reads und andere Inkonsistenzen eliminieren, finden Sie unter Isolationsstufen und Konsistenz.

  7. Korrigieren Sie als "Sales Manager" Ihren Fehler, indem Sie die ersten Änderungen zurücksetzen und den richtigen UPDATE-Befehl eingeben. Überprüfen Sie, ob die neuen Werte auch richtig sind.

    ROLLBACK;
    UPDATE Products
    SET UnitPrice = UnitPrice + 0.95
    WHERE NAME = 'Tee Shirt';
         
    ID Name UnitPrice
    300 Tee Shirt 9.95
    301 Tee Shirt 14.95
    302 Tee Shirt 14.95
    400 Baseball Cap 9.00
    ... ... ...
  8. Der "Accountant" weiß nicht, dass der von ihm berechnete Betrag nicht stimmt. Sie können den richtigen Wert sehen, wenn Sie die SELECT-Anweisung im Fenster des Accountants nochmals ausführen.

    SELECT SUM( Quantity * UnitPrice )
     AS Inventory
       FROM Products;
    Inventory
    6687.15
  9. Beenden Sie die Transaktion im Sales Manager-Fenster. Der "Sales Manager" würde eine COMMIT-Anweisung eingeben, um die Änderungen festzuschreiben, aber Sie sollten stattdessen eine ROLLBACK-Anweisung ausführen, um zu vermeiden, dass die lokale Kopie der SQL Anywhere-Beispieldatenbank geändert wird.

    ROLLBACK;

    Der "Accountant" erhält unwissentlich fehlerhafte Informationen von der Datenbank, da der Datenbankserver sowohl die Arbeit des "Sales Managers", als auch die des "Accountants" gleichzeitig bearbeitet.

  10. (Optional) Stellen Sie den Originalzustand der Beispieldatenbank (demo.db) mit den Schritten unter Die Beispieldatenbank neu erstellen (demo.db) wieder her.

 Snapshot-Isolation zur Vermeidung von Dirty Reads verwenden