Eine Transaktion in SQL ist eine Ausführungseinheit, die eine oder mehrere Aufgaben zusammenfasst. Eine Transaktion gilt als erfolgreich, wenn alle darin enthaltenen Aufgaben fehlerfrei ausgeführt werden.
Wenn jedoch eine der Aufgaben innerhalb einer Transaktion nicht ausgeführt werden kann, schlägt die gesamte Transaktion fehl. Eine Transaktion hat nur zwei Ergebnisse:erfolgreich oder fehlgeschlagen.
Ein praktisches Szenario
Betrachten Sie ein praktisches Beispiel für einen Geldautomaten (Automated Teller Machine). Sie gehen zum Geldautomaten und er fragt nach Ihrer Karte. Es führt eine Abfrage durch, um zu prüfen, ob die Karte gültig ist oder nicht. Als nächstes werden Sie nach Ihrem PIN-Code gefragt. Wieder wird eine Abfrage ausgeführt, um den PIN-Code abzugleichen. Der Geldautomat fragt Sie dann nach dem Betrag, den Sie abheben möchten, und Sie geben den gewünschten Betrag ein. Der Geldautomat führt eine weitere Abfrage durch, um diesen Betrag von Ihrem Konto abzubuchen, und gibt dann das Geld an Sie aus.
Was ist, wenn der Betrag von Ihrem Konto abgebucht wird und dann das System aufgrund eines Stromausfalls abstürzt, ohne dass die Scheine ausgegeben werden?
Dies ist problematisch, da der Kunde das Geld abgezogen bekommt, ohne Geld erhalten zu haben. Hier können Transaktionen praktisch sein.
Im Fall eines Systemabsturzes oder eines anderen Fehlers werden alle Aufgaben innerhalb der Transaktion zurückgesetzt. Im Falle eines Geldautomaten wird der Betrag daher Ihrem Konto wieder gutgeschrieben, wenn Sie ihn aus irgendeinem Grund nicht abheben können.
Was ist eine Transaktion?
Im einfachsten Fall ist eine Änderung in einer Datenbanktabelle eine Transaktion. Daher sind INSERT-, UPDATE- und DELETE-Anweisungen alle Transaktionsanweisungen. Wenn Sie eine Abfrage schreiben, wird eine Transaktion durchgeführt. Diese Transaktion kann jedoch nicht rückgängig gemacht werden. Wir werden unten sehen, wie Transaktionen erstellt, festgeschrieben und rückgängig gemacht werden, aber lassen Sie uns zuerst einige Dummy-Daten erstellen, mit denen wir arbeiten können.
Vorbereitung der Daten
Führen Sie das folgende Skript auf Ihrem Datenbankserver aus.
CREATE DATABASE schooldb CREATE TABLE student ( id INT PRIMARY KEY, name VARCHAR(50) NOT NULL, gender VARCHAR(50) NOT NULL, age INT NOT NULL, total_score INT NOT NULL, ) INSERT INTO student VALUES (1, 'Jolly', 'Female', 20, 500), (2, 'Jon', 'Male', 22, 545), (3, 'Sara', 'Female', 25, 600), (4, 'Laura', 'Female', 18, 400), (5, 'Alan', 'Male', 20, 500)
Das obige SQL-Skript erstellt eine Datenbank schooldb. In dieser Datenbank wird eine Tabelle student erstellt und dieser Tabelle werden einige Dummy-Daten hinzugefügt.
Ausführen von Abfragen ohne Transaktionen
Lassen Sie uns drei Standardabfragen ausführen. Wir verwenden derzeit keine Transaktionen.
INSERT INTO student VALUES (6, 'Suzi', 'Female', 25, 395) UPDATE student SET age = 'Six' WHERE id= 6 DELETE from student WHERE id = 6
Hier fügt die erste Abfrage einen Schülerdatensatz in die Datenbank ein. Die zweite Abfrage aktualisiert das Alter des Schülers und die dritte Abfrage löscht den neu eingefügten Datensatz.
Wenn Sie das obige Skript ausführen, werden Sie sehen, dass der Datensatz in die Datenbank eingefügt wird und dann ein Fehler während der Ausführung der zweiten Abfrage auftritt.
Wenn Sie sich die zweite Abfrage ansehen, aktualisieren wir das Alter, indem wir einen Zeichenfolgenwert in der Altersspalte speichern, der ganzzahlige Daten speichern kann. Daher wird ein Fehler ausgegeben. Die erste Abfrage wird jedoch weiterhin erfolgreich abgeschlossen. Das bedeutet, wenn Sie alle Datensätze aus der Schülertabelle auswählen, sehen Sie den neu eingefügten Datensatz.
[Tabellen-ID=23 /]
Sie können sehen, dass der Datensatz mit der ID=6 und dem Namen „Suzi“ in die Datenbank eingefügt wurde. Aber das Alter konnte nicht aktualisiert werden und die zweite Abfrage schlug fehl.
Was ist, wenn wir das nicht wollen? Was ist, wenn wir sicher sein wollen, dass entweder alle Abfragen erfolgreich ausgeführt werden oder gar keine der Abfragen? Hier sind Transaktionen praktisch.
Ausführen von Abfragen mit Transaktionen
Lassen Sie uns nun die drei obigen Abfragen innerhalb einer Transaktion ausführen.
Lassen Sie uns zuerst sehen, wie man eine Transaktion erstellt und festschreibt.
Eine Transaktion erstellen
Um eine Abfrage/Abfragen als Transaktion auszuführen, schließen Sie die Abfragen einfach in die Schlüsselwörter BEGIN TRANSACTION und COMMIT TRANSACTION ein. BEGIN TRANSACTION deklariert den Beginn einer TRANSACTION, während COMMIT TRANSACTION angibt, dass die Transaktion abgeschlossen wurde.
Lassen Sie uns drei neue Abfragen auf der Datenbank ausführen, die wir zuvor als Transaktion erstellt haben. Wir werden einen neuen Datensatz für einen neuen Schüler mit ID 7 hinzufügen.
BEGIN TRANSACTION INSERT INTO student VALUES (7, 'Jena', 'Female', 22, 456) UPDATE student SET age = 'Twenty Three' WHERE id= 7 DELETE from student WHERE id = 7 COMMIT TRANSACTION
Wenn die obige Transaktion ausgeführt wird, tritt erneut ein Fehler in der zweiten Abfrage auf, da wieder ein Wert vom Typ Zeichenfolge in der Altersspalte gespeichert wird, die nur Daten vom Typ Ganzzahl speichert.
Da der Fehler jedoch innerhalb einer Transaktion auftritt, werden alle Abfragen, die erfolgreich ausgeführt wurden, bevor dieser Fehler auftrat, automatisch rückgängig gemacht. Daher wird auch die erste Abfrage zurückgesetzt, die einen neuen Studentendatensatz mit der ID =7 und dem Namen „Jena“ einfügt.
Wenn Sie nun alle Datensätze aus der Schülertabelle auswählen, sehen Sie, dass der neue Datensatz für ‚Jena‘ nicht eingefügt wurde.
Manuelles Transaktions-Rollback
Wir wissen, dass, wenn eine Abfrage innerhalb einer Transaktion einen Fehler auslöst, die gesamte Transaktion, einschließlich aller bereits ausgeführten Abfragen, automatisch zurückgesetzt wird. Wir können eine Transaktion jedoch auch jederzeit manuell rückgängig machen.
Um eine Transaktion rückgängig zu machen, wird das Schlüsselwort ROLLBACK gefolgt vom Namen der Transaktion verwendet. Um eine Transaktion zu benennen, wird die folgende Syntax verwendet:
BEGIN TRANSACTION Transaction_name
Angenommen, wir möchten, dass unsere Schülertabelle keine Datensätze mit doppelten Schülernamen enthält. Wir werden einen Datensatz für einen neuen Schüler hinzufügen. Wir prüfen dann, ob ein Student mit identischem Namen wie der neu eingefügte Student in der Datenbank existiert. Wenn der Student mit diesem Namen noch nicht existiert, werden wir unsere Transaktion festschreiben. Wenn ein Student mit diesem Namen existiert, werden wir unsere Transaktion rückgängig machen. Wir werden in unserer Abfrage bedingte Anweisungen verwenden.
Schauen Sie sich die folgende Transaktion an:
DECLARE @NameCount int BEGIN TRANSACTION AddStudent INSERT INTO student VALUES (8, 'Jacob', 'Male', 21, 600) SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob' IF @NameCount > 1 BEGIN ROLLBACK TRANSACTION AddStudent PRINT 'A student with this name already exists' END ELSE BEGIN COMMIT TRANSACTION AddStudent PRINT 'New record added successfully' END
Sehen Sie sich das obige Skript genau an. Hier tut sich einiges.
In der ersten Zeile erstellen wir eine SQL-Variable NameCount vom Typ Integer.
Als nächstes beginnen wir eine Transaktion mit dem Namen „AddStudent“. Sie können Ihrer Transaktion einen beliebigen Namen geben.
Innerhalb der Transaktion haben wir einen neuen Datensatz für einen Schüler mit der ID =8 und dem Namen „Jacob“ eingefügt.
Als Nächstes zählen wir unter Verwendung der COUNT-Aggregatfunktion die Anzahl der Schülerdatensätze mit dem Namen „Jacob“ und speichern das Ergebnis in der Variablen „NameCount“.
Wenn der Wert der Variable größer als 1 ist, bedeutet dies, dass ein Schüler mit dem Namen „Jacob“ bereits in der Datenbank existiert. In diesem Fall ROLLBACKEN wir unsere Transaktion und DRUCKEN eine Nachricht auf dem Bildschirm, dass „ein Schüler mit diesem Namen bereits existiert“.
Falls nicht, schreiben wir unsere Transaktion fest und zeigen die Meldung „Neuer Datensatz erfolgreich hinzugefügt“ an.
Wenn Sie die obige Transaktion zum ersten Mal ausführen, gibt es keinen Schülerdatensatz mit dem Namen „Jacob“. Daher wird die Transaktion festgeschrieben und die folgende Nachricht ausgegeben:
Versuchen Sie nun, das folgende SQL-Skript auf dem Server auszuführen:
DECLARE @NameCount int BEGIN TRANSACTION AddStudent INSERT INTO student VALUES (9, 'Jacob', 'Male', 22, 400) SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob' IF @NameCount > 1 BEGIN ROLLBACK TRANSACTION AddStudent PRINT 'A student with this name already exists' END ELSE BEGIN COMMIT TRANSACTION PRINT 'New record added successfully' END
Auch hier fügen wir den Studentendatensatz mit der ID =9 und dem Namen „Jacob“ ein. Da bereits ein Schülerdatensatz mit dem Namen „Jacob“ in der Datenbank vorhanden ist, wird die Transaktion rückgängig gemacht und die folgende Meldung wird gedruckt:
Nützliche Links
- Klassen für SQL-Transaktionen