Transaktionen und Isolationsstufen verwenden
Praktische Einführung in Isolationsstufen
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.
Tipps: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. |
In diesem Beispiel spielen Sie die Rolle von zwei Personen, die die Beispieldatenbank gleichzeitig benutzen.
Starten Sie Interactive SQL.
Verbinden Sie sich als "Sales Manager" mit der Beispieldatenbank.
Wählen Sie im Dialogfeld "Verbinden" die ODBC-Datenquelle ASA 9.0 Sample.
Geben Sie auf der Registerkarte "Erweitert" folgende Zeichenfolge ein, um die Identifikation des Fensters zu erleichtern:
ConnectionName=Sales Manager
Klicken Sie auf OK, um eine Verbindung herzustellen.
Starten Sie eine zweite Instanz von Interactive SQL.
Verbinden Sie sich als "Accountant" mit der Beispieldatenbank.
Wählen Sie im Dialogfeld "Verbinden" die ODBC-Datenquelle ASA 9.0 Sample.
Geben Sie auf der Registerkarte "Erweitert" folgende Zeichenfolge ein, um die Identifikation des Fensters zu erleichtern:
ConnectionName=Accountant
Klicken Sie auf OK, um eine Verbindung herzustellen.
Erhöhen Sie als "Sales Manager" die Preise aller T-Shirts um $0.95.
Führen Sie im Fenster Sales Manager folgende Befehle aus:
SELECT id, name, unit_price FROM product; UPDATE PRODUCT SET unit_price = unit_price + 95 WHERE NAME = 'Tee Shirt'
Das Ergebnis sieht folgendermaßen aus:
| id | name | unit_price |
|---|---|---|
| 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.
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 * unit_price ) AS inventory FROM product
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.
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 product SET unit_price = unit_price + 0.95 WHERE NAME = 'Tee Shirt';
| id | name | unit_price |
|---|---|---|
| 300 | Tee Shirt | 9.95 |
| 301 | Tee Shirt | 14.95 |
| 302 | Tee Shirt | 14.95 |
| 400 | Baseball Cap | 9.00 |
| ... | ... | ... |
Der "Accountant" weiß nicht, dass der von ihm berechnete Betrag nicht stimmt. Sie können den richtigen Wert sehen, wenn Sie die SELECT-Anweisung in seinem Fenster nochmals ausführen.
SELECT SUM( quantity * unit_price ) AS inventory FROM product;
| inventory | |
|---|---|
| 6687.15 |
Beenden Sie die Transaktion im Sales Manager-Fenster. Mit einem COMMIT-Befehl werden seine Änderungen festgeschrieben, aber Sie wollen vielleicht lieber einen ROLLBACK-Befehl eingeben, damit die Demonstrationsdatenbank auf Ihrem Rechner nicht verä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.
SQL Anywhere Studio 9.0.1
Copyright © 1989–2004 Sybase Inc. Teil-Copyright © 2001–2004 iAnywhere Solutions Inc. Alle Rechte vorbehalten.