11. Transaktionen steuern
Sicherungspunkte bei Transaktionen
Die letzten zehn Tage haben Sie nahezu alles gelernt, was man mit Daten in einer relationalen Datenbank anstellen kann. Beispielsweise wissen Sie, wie man Daten mit der SQL-Anweisung SELECT aus Tabellen abruft und das Ergebnis von Bedingungen, die der Benutzer angibt, abhängig macht. Außerdem haben Sie mit Anweisungen zur Datenmanipulation wie INSERT, UPDATE und DELETE gearbeitet. Damit gehören Sie in den Kreis der Benutzer mit einem mittleren Kenntnisstand in bezug auf SQL und Datenbanken. Gegebenenfalls könnten Sie bereits eine Datenbank mit den zugehörigen Tabellen aufbauen, wobei jede Tabelle verschiedene Felder mit unterschiedlichen Datentypen enthält. Mit den geeigneten Entwurfsverfahren können Sie die Informationen aus der Datenbank in eine leistungsfähige Anwendung übertragen.
Ziele
Wenn Sie nur hin und wieder mit SQL arbeiten und gelegentlich Daten aus einer Datenbank abrufen müssen, dürfte Ihnen das Material der ersten zehn Tage bereits den größten Teil der erforderlichen Informationen bieten. Haben Sie allerdings vor, eine professionelle Anwendung zu entwickeln, die sich auf eine relationale Datenbank stützt, sind Ihnen die Themen der nächsten vier Tage - Transaktionssteuerung, Sicherheit, Programme mit eingebettetem SQL und Datenbankprozeduren - eine unerläßliche Hilfe. Wir beginnen mit der Transaktionssteuerung.
Die heutige Lektion erläutert ...
Für die heutigen Beispiele kommen sowohl Personal Oracle8 als auch SQL Server von Sybase zum Einsatz. Der Dokumentation zu Ihrem Datenbank-Managementsystem können Sie kleinere Unterschiede in der Syntax entnehmen. |
Transaktionssteuerung
Transaktionssteuerung - oder Transaktionsmanagement - bezieht sich auf die Fähigkeit eines relationalen Datenbank-Managementsystems, Datenbanktransaktionen auszuführen. Transaktionen sind Arbeitseinheiten, die als Gruppe in einer logischen Reihenfolge, und zwar erfolgreich oder überhaupt nicht auszuführen sind. Der Begriff Arbeitseinheit
In den kommenden Monaten oder Jahren werden Sie wahrscheinlich Anwendungen für mehrere Benutzer über ein Netzwerk implementieren. Client/Server-Umgebungen sind speziell für diesen Zweck ausgelegt. Traditionell unterstützt ein Server (in diesem Fall ein Datenbank-Server) mehrere daran angeschlossene Netzwerkverbindungen. Wie es bei neuen Technologien oft der Fall ist, führt die erweiterte Flexibilität zu komplizierteren Bedingungen in der Systemumgebung. Sehen Sie sich dazu die Bankanwendung an, die die nächsten Absätze beschreiben.
Die Bankanwendung
Die First Federal Financial Bank hat Sie beauftragt, eine Anwendung für Schecktransaktionen einzurichten, die Buchungen auf den Girokonten der Kunden realisiert. Sie haben eine hübsche Datenbank aufgebaut, die getestet wurde und scheinbar korrekt arbeitet. Wenn man $20 vom Konto abbucht, verschwindet dieser Betrag tatsächlich aus der Datenbank. Fügen Sie dem Girokonto $50.25 hinzu, zeigt sich diese Einzahlung ebenfalls wie erwartet. Stolz verkünden Sie Ihrem Chef, daß das System bereit ist. Daraufhin werden mehrere Computer in einer örtlichen Filiale eingerichtet, um die Arbeit mit Ihrer Anwendung aufzunehmen.
Nach kurzer Zeit bemerken Sie einen Zustand, auf den Sie nicht vorbereitet waren: Während ein Schalterbeamter einen Scheck deponiert, hebt ein anderer Angestellter Geld vom selben Konto ab. Innerhalb von Minuten sind die Salden auf vielen Konten nicht mehr korrekt, da viele Benutzer die Tabellen gleichzeitig aktualisieren. Leider überschreiben sich diese Aktualisierungen untereinander. Kurz danach wird Ihre Anwendung durch eine Wartungsmaßnahme offline geschaltet. Dieses Probleme arbeiten wir anhand einer Datenbank namens GIROKONTEN durch. Innerhalb dieser Datenbank gibt es zwei Tabellen, die in den Tabellen 11.1 und 11.2 dargestellt sind.
Tabelle 11.1: Die Tabelle KUNDEN
NAME |
ADRESSE |
STADT |
STAAT |
ZIP |
KUNDEN_NR |
Bill Turner |
725 N. Deal Parkway |
Washington |
DC |
20085 |
1 |
John Keith |
1220 Via De Luna Dr. |
Jacksonville |
FL |
33581 |
2 |
Mary Rosenberg |
482 Wannamaker Avenue |
Williamsburg |
VA |
23478 |
3 |
David Blanken |
405 N. Davis Highway |
Greenville |
SC |
29652 |
4 |
Rebecca Little |
7753 Woods Lane |
Houston |
TX |
38764 |
5 |
Tabelle 11.2: Die Tabelle SALDEN
SALDO_MW |
SALDO_AKT |
KONTO_ID |
1298.53 |
854.22 |
1 |
5427.22 |
6015.96 |
2 |
211.25 |
190.01 |
3 |
73.79 |
25.87 |
4 |
1285.90 |
1473.75 |
5 |
1234.56 |
1543.67 |
6 |
345.25 |
348.03 |
7 |
Nehmen wir nun an, daß Ihre Anwendung eine SELECT-Operation ausführt und die folgenden Daten für Bill Turner abruft:
NAME: Bill Turner
ADRESSE: 725 N. Deal Parkway
STADT: Washington
STAAT: DC
ZIP: 20085
KUNDEN_NR: 1
Während diese Informationen abgerufen werden, aktualisiert ein anderer Benutzer mit einer Verbindung zu dieser Datenbank die Adreßangaben zu Bill Turner:
SQL> UPDATE KUNDEN SET ADRESSE = '11741 Kingstowne Road'
WHERE NAME = 'Bill Turner';
Wie Sie sehen, können die vorher abgerufenen Informationen nun ungültig sein, wenn die Aktualisierung in der Mitte Ihrer SELECT-Operation auftritt. Wenn Ihre Anwendung einen Brief an Bill Turner ausgelöst hat, wäre die verwendete Adresse nun falsch. Es liegt auf der Hand, daß man die Adresse auf einem abgeschickten Brief nicht mehr ändern kann. Wenn Sie allerdings mit einer Transaktion gearbeitet hätten, ließe sich diese Datenänderung erkennen, und man könnte alle anderen Operationen rückgängig machen.
Eine Transaktion beginnen
Transaktionen sind recht einfach zu implementieren. Wir untersuchen sowohl die SQL-Syntax im Oracle-RDBMS als auch die von Sybase SQL Server.
Alle Datenbanksysteme mit Transaktionsverarbeitung müssen dem System explizit mitteilen können, daß eine Transaktion beginnt. (Wie Sie wissen, ist eine Transaktion eine Folge von Änderungen, die einen Anfang und ein Ende hat.) Bei Personal Oracle8 sieht die entsprechende Syntax wie folgt aus:
SET TRANSACTION {READ ONLY | USE ROLLBACK SEGMENT Segment}
Der SQL-Standard legt fest, daß die SQL-Implementierung der Datenbanken das folgerichtige Lesen auf Anweisungsebene unterstützen muß. Das heißt, die Daten müssen während der Ausführung einer Anweisung konsistent bleiben. Allerdings müssen die Daten in vielen Situationen über eine ganze Arbeitseinheit hinweg gültig bleiben und nicht nur innerhalb einer einzelnen Anweisung. Mit Oracle kann der Benutzer den Beginn einer Transaktion mit der Anweisung SET TRANSACTION festlegen. Wenn man die Informationen zu Bill Turner untersuchen möchte und eine Änderung der Daten verhindern will, kann man folgendes ausführen:
SQL> SET TRANSACTION READ ONLY;
SQL> SELECT * FROM KUNDEN
WHERE NAME = 'Bill Turner';
--- Andere Operationen ausführen ---
SQL> COMMIT;
Auf die COMMIT-Anweisung gehen wir später ein. Mit der Option SET TRANSACTION READ ONLY läßt sich eine Gruppe von Datensätzen sperren, bis die Transaktion abgeschlossen ist. Man kann die Option READ ONLY bei den folgenden Befehlen verwenden:
Die Option USE ROLLBACK SEGMENT teilt Oracle mit, in welchem Datenbanksegment der Speicherbereich für Rollback-Aktionen anzulegen ist. Diese Option ist eine Oracle-Erweiterung zur Standard-SQL-Syntax. In der Oracle-Dokumentation finden Sie weitere Informationen, wie man Segmente bei der Verwaltung einer Datenbank einsetzt.
Die Sprache Transact-SQL von SQL Server implementiert den Befehl BEGIN TRANSACTION mit der folgenden Syntax:
begin {transaction | tran} [Transaktionsname]
Diese Implementierung unterscheidet sich ein wenig von der Oracle-Implementierung. (Sybase erlaubt nicht die Angabe der Option READ ONLY.) Allerdings kann man mit Sybase der Transaktion einen Namen geben, solange es sich um die äußerste Transaktion in einem Satz verschachtelter Transaktionen handelt.
Die folgende Anweisungsgruppe zeigt verschachtelte Transaktionen in der Sprache Transact-SQL von Sybase:
1> begin transaction KONTO_NEU
2> insert KUNDEN values ('Izetta Parsons', '1285 Pineapple Highway', 'Greenville', 'AL', 32854, 6)
3> if exists(select * from KUNDEN where NAME = 'Izetta Parsons')
4> begin
5> begin transaction
6> insert SALDEN values(1250.76, 1431.26, 8)
7> end
8> else
9> rollback transaction
10> if exists(select * from SALDEN where KONTO_ID = 8)
11> begin
12> begin transaction
13> insert KONTEN values(8, 6)
14> end
15> else
16> rollback transaction
17> if exists (select * from KONTEN where KONTO_ID = 8 and KUNDEN_NR = 6)
18> commit transaction
19> else
20> rollback transaction
21> go
Momentan brauchen Sie sich noch nicht um die Anweisungen ROLLBACK TRANSACTION und COMMIT TRANSACTION zu kümmern. Dieses Beispiel soll in erster Linie die verschachtelte Transaktion - oder eine Transaktion innerhalb einer Transaktion - zeigen.
Beachten Sie, daß die anfängliche Transaktion (KONTO_NEU) in Zeile 1 beginnt. Nach dem ersten Einfügen wird geprüft, ob die INSERT-Operation erfolgreich verlaufen ist. Eine weitere Transaktion beginnt in Zeile 5. Diese Konstruktion bezeichnet man als
Verschiedene Datenbanken unterstützen die automatische Bestätigung der Transaktion mit der Option AUTOCOMMIT. Diese Option läßt sich mit dem SET-Befehl einrichten:
SET AUTOCOMMIT [ON | OFF]
Per Vorgabe wird der Befehl AUTOCOMMIT ON beim Start ausgeführt. Er weist SQL an, automatisch alle von Ihnen ausgeführten Anweisungen zu bestätigen. Wenn Sie diese Befehle nicht automatisch ausführen möchten, setzen Sie die Option AUTOCOMMIT auf OFF:
SET AUTOCOMMIT OFF
Ermitteln Sie anhand der Dokumentation Ihres Datenbanksystems, wie Sie eine Transaktion einleiten. |
Eine Transaktion beenden
Die Oracle-Syntax zum Beenden einer Transaktion lautet wie folgt:
COMMIT [WORK]
[ COMMENT 'Text'
| FORCE 'Text' [, Integer] ] ;
Der gleiche Befehl mit der Syntax von Sybase sieht folgendermaßen aus:
COMMIT (TRANSACTION | TRAN) (TRANSAKTIONSNAME)
Der Befehl COMMIT speichert alle Änderungen, die während einer Transaktion ausgeführt wurden. Die Ausführung einer COMMIT-Anweisung vor dem Beginn einer Transaktion stellt sicher, daß keine Fehler aufgetreten sind und keine vorherige Transaktion anhängig ist.
Das folgende Beispiel verifiziert, daß der Befehl COMMIT für sich allein verwendet werden kann, ohne daß man einen Fehler vom Datenbanksystem zurückerhält.
SQL> COMMIT;
SQL> SET TRANSACTION READ ONLY;
SQL> SELECT * FROM KUNDEN
WHERE NAME = 'Bill Turner';
--- Andere Operationen ausführen ---
SQL> COMMIT;
Das folgende Beispiel zeigt den Einsatz der COMMIT-Anweisung in Oracle-SQL:
SQL> SET TRANSACTION;
SQL> INSERT INTO KUNDEN VALUES
('John MacDowell', '2000 Lake Lunge Road', 'Chicago', 'IL', 42854, 7);
SQL> COMMIT;
SQL> SELECT * FROM KUNDEN;
Tabelle 11.3: Die Tabelle KUNDEN
NAME |
ADRESSE |
STADT |
STAAT |
ZIP |
KUNDEN_NR |
Bill Turner |
725 N. Deal Parkway |
Washington |
DC |
20085 |
1 |
John Keith |
1220 Via De Luna Dr. |
Jacksonville |
FL |
33581 |
2 |
Mary Rosenberg |
482 Wannamaker Avenue |
Williamsburg |
VA |
23478 |
3 |
David Blanken |
405 N. Davis Highway |
Greenville |
SC |
29652 |
4 |
Rebecca Little |
7753 Woods Lane |
Houston |
TX |
38764 |
5 |
Izetta Parsons |
1285 Pineapple Highway |
Greenville |
AL |
32854 |
6 |
John MacDowell |
2000 Lake Lunge Road |
Chicago |
IL |
42854 |
7 |
Eine COMMIT-Anweisung in Sybase-SQL sieht zum Beispiel folgendermaßen aus:
1> begin transaction
2> insert into KUNDEN values
('John MacDowell', '2000 Lake Lunge Road', 'Chicago', 'IL', 42854, 7)
3> commit transaction
4> go
1> select * from KUNDEN
2> go
Tabelle 11.4: Die Tabelle KUNDEN
NAME |
ADRESSE |
STADT |
STAAT |
ZIP |
KUNDEN_NR |
Bill Turner |
725 N. Deal Parkway |
Washington |
DC |
20085 |
1 |
John Keith |
1220 Via De Luna Dr. |
Jacksonville |
FL |
33581 |
2 |
Mary Rosenberg |
482 Wannamaker Avenue |
Williamsburg |
VA |
23478 |
3 |
David Blanken |
405 N. Davis Highway |
Greenville |
SC |
29652 |
4 |
Rebecca Little |
7753 Woods Lane |
Houston |
TX |
38764 |
5 |
Izetta Parsons |
1285 Pineapple Highway |
Greenville |
AL |
32854 |
6 |
John MacDowell |
2000 Lake Lunge Road |
Chicago |
IL |
42854 |
7 |
Die obigen Anweisungen realisieren das gleiche wie bei Verwendung der Syntax von Oracle8. Allerdings stellt man durch Ausführung des COMMIT-Befehls unmittelbar nach Beginn der Transaktion sicher, daß die neue Transaktion korrekt ausgeführt wird.
Der Befehl COMMIT WORK ist äquivalent zum Befehl COMMIT (bzw. COMMIT TRANSACTION von Sybase) und wird nur bereitgestellt, um der Syntax von ANSI SQL zu entsprechen. |
Die Transaktion abbrechen
Während einer laufenden Transaktion findet gewöhnlich eine Fehlerprüfung statt, um die erfolgreiche Ausführung festzustellen. Man kann eine Transaktion selbst nach vollständiger Abarbeitung noch rückgängig machen, indem man den Befehl ROLLBACK ausführt. Dieser Befehl ist allerdings noch vor einem COMMIT-Befehl zu geben. Die ROLLBACK-Anweisung ist aus einer Transaktion heraus auszuführen. Die Anweisung ROLLBACK macht die Transaktion rückgängig und stellt den Anfangszustand wieder her. Mit anderen Worten erhält man den Zustand der Datenbank vor Beginn der Transaktion. Die Syntax für diesen Befehl in Oracle8 lautet folgendermaßen:
ROLLBACK [WORK]
[ TO [SAVEPOINT] Sicherungspunkt
| FORCE 'Text' ]
Der Befehl sieht einen Sicherungspunkt für die Transaktion vor. Auf dieses Verfahren gehen wir weiter hinten in diesem Kapitel ein.
Die ROLLBACK-Anweisung von Sybase Transact-SQL sieht dem COMMIT-Befehl sehr ähnlich:
rollback {transaction | tran | work}
[Transaktionsname | Sicherungspunktname]
Eine Befehlsfolge läßt sich in Oracle-SQL zum Beispiel wie folgt formulieren:
SQL> SET TRANSACTION;
SQL> INSERT INTO KUNDEN VALUES
('Bubba MacDowell', '2222 Blue Lake Way', 'Austin', 'TX', 39874, 8);
SQL> ROLLBACK;
SQL> SELECT * FROM KUNDEN;
Tabelle 11.5: Die Tabelle KUNDEN
NAME |
ADRESSE |
STADT |
STAAT |
ZIP |
KUNDEN_NR |
Bill Turner |
725 N. Deal Parkway |
Washington |
DC |
20085 |
1 |
John Keith |
1220 Via De Luna Dr. |
Jacksonville |
FL |
33581 |
2 |
Mary Rosenberg |
482 Wannamaker Avenue |
Williamsburg |
VA |
23478 |
3 |
David Blanken |
405 N. Davis Highway |
Greenville |
SC |
29652 |
4 |
Rebecca Little |
7753 Woods Lane |
Houston |
TX |
38764 |
5 |
Izetta Parsons |
1285 Pineapple Highway |
Greenville |
AL |
32854 |
6 |
John MacDowell |
2000 Lake Lunge Road |
Chicago |
IL |
42854 |
7 |
Die äquivalente Befehlsfolge sieht in Sybase-SQL folgendermaßen aus:
1> begin transaction
2> insert into KUNDEN values
('Bubba MacDowell', '2222 Blue Lake Way', 'Austin', 'TX', 39874, 8);
3> rollback transaction
4> go
1> SELECT * FROM KUNDEN
2> go
Tabelle 11.6: Die Tabelle KUNDEN
NAME |
ADRESSE |
STADT |
STAAT |
ZIP |
KUNDEN_NR |
Bill Turner |
725 N. Deal Parkway |
Washington |
DC |
20085 |
1 |
John Keith |
1220 Via De Luna Dr. |
Jacksonville |
FL |
33581 |
2 |
Mary Rosenberg |
482 Wannamaker Avenue |
Williamsburg |
VA |
23478 |
3 |
David Blanken |
405 N. Davis Highway |
Greenville |
SC |
29652 |
4 |
Rebecca Little |
7753 Woods Lane |
Houston |
TX |
38764 |
5 |
Izetta Parsons |
1285 Pineapple Highway |
Greenville |
AL |
32854 |
6 |
John MacDowell |
2000 Lake Lunge Road |
Chicago |
IL |
42854 |
7 |
Wie man sieht, wurde der neue Datensatz nicht hinzugefügt, da die ROLLBACK-Anweisung die INSERT-Operation rückgängig gemacht hat.
Nehmen wir an, daß Sie eine Anwendung für eine grafische Benutzeroberfläche wie etwa Microsoft Windows schreiben. In einem Dialogfeld fragen Sie eine Datenbank ab und erlauben dem Benutzer, Werte zu ändern. Wenn der Benutzer OK wählt, speichert die Datenbank die Änderungen. Wählt der Benutzer Abbrechen, werden die Änderungen verworfen. Hier bietet sich das Arbeiten mit einer Transaktion an.
Das folgende Listing verwendet die Syntax von Oracle SQL. Beachten Sie die Eingabeaufforderung SQL> und die Zeilennummern. Das sich anschließende Listing arbeitet mit der SQL-Syntax von Sybase. Hier gibt es keine Eingabeaufforderung wie SQL>. |
Beim Öffnen des Dialogfelds läßt man die folgende SQL-Anweisung ausführen:
SQL> SET TRANSACTION;
SQL> SELECT KUNDEN.NAME, SALDEN.SALDO_AKT, SALDEN.KONTO_ID
2 FROM KUNDEN, SALDEN
3 WHERE KUNDEN.NAME = 'Rebecca Little'
4 AND KUNDEN.KUNDEN_NR = SALDEN.KONTO_ID;
Das Dialogfeld erlaubt dem Benutzer, den aktuellen Kontostand zu ändern, so daß man diesen Wert in die Datenbank zurückspeichern muß.
Wenn der Benutzer OK wählt, startet die Aktualisierung.
SQL> UPDATE SALDEN SET SALDO_AKT = 'WERT_NEU' WHERE KONTO_ID = 6;
SQL> COMMIT;
Wählt der Benutzer Abbrechen, wird die ROLLBACK-Anweisung ausgeführt.
SQL> ROLLBACK;
In Sybase-SQL sehen die beim Öffnen des Dialogfelds auszuführenden SQL-Anweisungen folgendermaßen aus:
1> begin transaction
2> select KUNDEN.NAME, SALDEN.SALDO_AKT, SALDEN.KONTO_ID
3> from KUNDEN, SALDEN
4> where KUNDEN.NAME = 'Rebecca Little'
5> and KUNDEN.KUNDEN_NR = SALDEN.KONTO_ID
6> go
Das Dialogfeld erlaubt dem Benutzer, den aktuellen Kontostand zu ändern, so daß man diesen Wert wieder in die Datenbank übernehmen kann.
Auch hier startet die Aktualisierung, wenn der Benutzer die Schaltfläche OK wählt.
1> update SALDEN set SALDO_AKT = 'WERT_NEU' WHERE KONTO_ID = 6
2> commit transaction
3> go
Durch Wahl von Abbrechen löst der Benutzer die ROLLBACK-Anweisung aus.
1> rollback transaction
2> go
Die ROLLBACK-Anweisung bricht die gesamte Transaktion ab. Wenn man Transaktionen verschachtelt, bricht die ROLLBACK-Anweisung alle Transaktionen ab und stellt den Zustand vor Beginn der äußersten Transaktion wieder her.
Wenn momentan keine Transaktion aktiv ist, hat der Aufruf der ROLLBACK-Anweisung oder des COMMIT-Befehls keine Auswirkung auf das Datenbanksystem. (Stellen Sie sich diese Befehle einfach als tote Befehle vor.)
Sobald man die COMMIT-Anweisung ausgeführt hat, werden alle Operationen der Transaktion wirksam. Jetzt ist es zu spät, die Transaktion rückgängig zu machen.
Sicherungspunkte bei Transaktionen
Das Rückgängigmachen einer Transaktion bricht die gesamte Transaktion ab. Nehmen wir nun aber an, daß wir eine Transaktion nur zur Hälfte bis zu einem bestimmten Punkt der Anweisungsfolge rückgängig machen wollen. Sowohl Sybase als auch Oracle SQL erlauben das Sichern der Transaktion mit einem Sicherungspunkt (Savepoint). Von nun an wird beim Auslösen eines ROLLBACK-Befehls die Transaktion nur ab diesem Sicherungspunkt rückgängig gemacht. Alle bis zu diesem Sicherungspunkt ausgeführten Aktionen werden gespeichert. Die Syntax für das Erzeugen eines Sicherungspunkts in Oracle SQL lautet wie folgt:
SAVEPOINT Sicherungspunktname;
In SQL Server erzeugt man einen Sicherungspunkt nach folgender Syntax:
save transaction Sicherungspunktname
Das nächste Beispiel verwendet die Syntax von Oracle SQL.
SQL> SET TRANSACTION;
SQL> UPDATE SALDEN SET SALDO_AKT = 25000 WHERE KONTO_ID = 5;
SQL> SAVEPOINT sicher;
SQL> DELETE FROM SALDEN WHERE KONTO_ID = 5;
SQL> ROLLBACK TO SAVEPOINT sicher;
SQL> COMMIT;
SQL> SELECT * FROM SALDEN;
Tabelle 11.7: Die Tabelle SALDEN
SALDO_MW |
SALDO_AKT |
KONTO_ID |
1298.53 |
854.22 |
1 |
5427.22 |
6015.96 |
2 |
211.25 |
190.01 |
3 |
73.79 |
25.87 |
4 |
1285.90 |
25000.00 |
5 |
1234.56 |
1543.67 |
6 |
345.25 |
348.03 |
7 |
1250.76 |
1431.26 |
8 |
Das folgende Beispiel arbeitet nach der Syntax von Sybase SQL:
1> begin transaction
2> update SALDEN set SALDO_AKT = 25000 where KONTO_ID = 5
3> save transaction sicher
4> delete from SALDEN where KONTO_ID = 5
5> rollback transaction sicher
6> commit transaction
7> go
1> select * from SALDEN
2> go
Tabelle 11.8: Die Tabelle SALDEN
SALDO_MW |
SALDO_AKT |
KONTO_ID |
1298.53 |
854.22 |
1 |
5427.22 |
6015.96 |
2 |
211.25 |
190.01 |
3 |
73.79 |
25.87 |
4 |
1285.90 |
25000.00 |
5 |
1234.56 |
1543.67 |
6 |
345.25 |
348.03 |
7 |
1250.76 |
1431.26 |
8 |
Die obigen Beispiele haben einen Sicherungspunkt namens sicher erzeugt. An der Datenbank wurde eine Aktualisierung vorgenommen, die den Wert der Spalte SALDO_AKT der Tabelle SALDEN geändert hat. Dann haben Sie diese Änderung als Sicherungspunkt gespeichert. An diese Sicherung schließt sich eine DELETE-Anweisung an. Allerdings haben Sie dann unmittelbar darauf die Transaktion bis zum Sicherungspunkt rückgängig gemacht. Mit Ausführung von COMMIT TRANSACTION wurden dann alle Befehle bis zum Sicherungspunkt bestätigt. Hätten Sie ein ROLLBACK TRANSACTION nach dem Befehl ROLLBACK TRANSACTION Sicherungspunktname ausgeführt, wäre die gesamte Transaktion rückgängig gemacht worden, und es hätten keine Änderungen stattgefunden.
Das folgende Beispiel verwendet die Syntax von Oracle SQL:
SQL> SET TRANSACTION;
SQL> UPDATE SALDEN SET SALDO_AKT = 25000 WHERE KONTO_ID = 5;
SQL> SAVEPOINT sicher;
SQL> DELETE FROM SALDEN WHERE KONTO_ID = 5;
SQL> ROLLBACK TO SAVEPOINT sicher;
SQL> ROLLBACK;
SQL> SELECT * FROM SALDEN;
Tabelle 11.9: Die Tabelle SALDEN
SALDO_MW |
SALDO_AKT |
KONTO_ID |
1298.53 |
854.22 |
1 |
5427.22 |
6015.96 |
2 |
211.25 |
190.01 |
3 |
73.79 |
25.87 |
4 |
1285.90 |
1473.75 |
5 |
1234.56 |
1543.67 |
6 |
345.25 |
348.03 |
7 |
1250.76 |
1431.26 |
8 |
Im nächsten Beispiel kommt die Syntax von Sybase SQL zum Einsatz:
1> begin transaction
2> update SALDEN set SALDO_AKT = 25000 where KONTO_ID = 5
3> save transaction sicher
4> delete from SALDEN where KONTO_ID = 5
5> rollback transaction sicher
6> rollback transaction
7> go
1> select * from SALDEN
2> go
Tabelle 11.10: Die Tabelle SALDEN
SALDO_MW |
SALDO_AKT |
KONTO_ID |
1298.53 |
854.22 |
1 |
5427.22 |
6015.96 |
2 |
211.25 |
190.01 |
3 |
73.79 |
25.87 |
4 |
1285.90 |
1473.75 |
5 |
1234.56 |
1543.67 |
6 |
345.25 |
348.03 |
7 |
1250.76 |
1431.26 |
8 |
Zusammenfassung
Eine Transaktion kann man als Arbeitseinheit definieren. Sie führt gewöhnlich eine Folge von Operationen aus, die von vorher ausgeführten Operationen abhängig sind. Wenn eine dieser Operationen scheitert oder sich die Daten aus irgendwelchen Gründen ändern, sollte man die restlichen Aufträge in einer Transaktion stornieren. Bei korrekter Ausführung aller Anweisungen speichert man die gesamte Arbeit der Transaktion.
Das Abbrechen einer Transaktion bezeichnet man als Rückgängigmachen (Rollback), die Speicherung der Arbeit einer korrekt ausgeführten Transaktion als Bestätigung (Commit). Die SQL-Syntax unterstützt diese beiden Prozesse in der Art der folgenden beiden Anweisungen:
BEGIN TRANSACTION
Anweisung1
Anweisung2
Anweisung3
ROLLBACK TRANSACTION
oder
BEGIN TRANSACTION
Anweisung1
Anweisung2
Anweisung3
COMMIT TRANSACTION
Fragen & Antworten
Frage:
Wenn bei einer Gruppe von Transaktionen lediglich eine Transaktion scheitert, werden dann die restlichen Transaktionen verarbeitet?
Antwort:
Nein. Die Gruppe muß sich insgesamt erfolgreich ausführen lassen.
Frage:
Nach Ausführung des COMMIT-Befehls habe ich festgestellt, daß ich einen Fehler gemacht habe. Wie kann ich diesen Fehler korrigieren?
Antwort:
Verwenden Sie die Befehle DELETE, INSERT und UPDATE.
Frage:
Muß ich nach jeder Transaktion den COMMIT-Befehl ausführen?
Antwort:
Nein. Es ist aber sicherer. Man vergewissert sich damit, daß keine Fehler aufgetreten und keine vorherigen Transaktionen anhängig sind.
Workshop
Kontrollfragen
1. Bricht ein ROLLBACK-TRANSACTION-Befehl bei verschachtelten Transaktionen die aktuelle Transaktion ab und macht den Anweisungsstapel bis in die höchste Ebene der Transaktion rückgängig? Warum beziehungsweise warum nicht?
2. Kann man mit Sicherungspunkten bestimmte Teile einer Transaktion »absichern«? Warum beziehungsweise warum nicht?
3. Kann man einen COMMIT-Befehl für sich allein verwenden, oder muß man ihn einbetten?
4. Wenn man nach Ausführung des COMMIT-Befehls einen Fehler feststellt, läßt sich dann trotzdem noch der ROLLBACK-Befehl ausführen?
5. Wenn man in einer Transaktion mit einem Sicherungspunkt arbeitet, werden dann alle bis zu diesem Punkt gelaufenen Aktionen automatisch gespeichert?
Übungen
1. Korrigieren Sie (falls erforderlich) die folgenden Anweisungen gemäß Syntax von Personal Oracle8:
SQL> START TRANSACTION
INSERT INTO KUNDEN VALUES
('SMITH', 'JOHN')
SQL> COMMIT;
2. Korrigieren Sie (falls erforderlich) die folgenden Anweisungen gemäß Syntax von Personal Oracle8:
SQL> SET TRANSACTION;
UPDATE SALDEN SET SALDO_AKT = 25000;
SQL> COMMIT;
3. Korrigieren Sie (falls erforderlich) die folgenden Anweisungen gemäß Syntax von Personal Oracle8:
SQL> SET TRANSACTION;
INSERT INTO SALDEN VALUES
('567.34', '230.00', '8');
SQL> ROLLBACK;