In SQL ist es oft erforderlich, das Szenario „alles oder nichts“ bei massiven Änderungen zu implementieren — entweder alle Änderungen werden übernommen, oder sie werden bei einem Fehler zurückgesetzt. Dieser Ansatz wird durch die Verwendung von Transaktionen erreicht. Die gespeicherte Prozedur sollte eine Transaktion explizit starten (BEGIN TRANSACTION), die entsprechenden Operationen einrahmen, Fehler behandeln, und im Falle eines Fehlers ROLLBACK ausführen, andernfalls COMMIT.
Es sollte nicht vergessen werden, die Fehler korrekt über Konstruktionen wie TRY...CATCH (SQL Server) oder EXCEPTION (PostgreSQL) zu behandeln.
Beispiel für SQL Server:
CREATE PROCEDURE MassUpdate AS BEGIN BEGIN TRY BEGIN TRANSACTION; UPDATE Orders SET Status = 'Processed' WHERE Status = 'Pending'; UPDATE Inventory SET Stock = Stock - 1 WHERE ProductID IN (SELECT ProductID FROM Orders WHERE Status = 'Processed'); COMMIT TRANSACTION; END TRY BEGIN CATCH ROLLBACK TRANSACTION; -- Fehlerprotokollierung THROW; END CATCH END
Frage: Ist es ausreichend, nur BEGIN TRANSACTION und COMMIT zu verwenden, um eine korrekte Rückgängigmachung von Änderungen bei Fehlern in allen unterstützten DBMS zu gewährleisten?
Antwort: Nein, eine Transaktion selbst fängt keine Ausnahmen ab. Es ist notwendig, Handler (TRY...CATCH oder ähnliche) zu verwenden, um den Fehler abzufangen und ROLLBACK explizit aufzurufen. In einigen DBMS (z. B. MySQL mit autocommit) kann auch zusätzliche Konfiguration erforderlich sein.
Beispiel für fehlerhaften Code (SQL Server):
BEGIN TRANSACTION; UPDATE Users SET Name = 'Ivan' WHERE ID = 1; UPDATE Orders SET Amount = Amount/0 WHERE UserID = 1; -- Division durch 0 Fehler COMMIT TRANSACTION;
In diesem Fall bleibt die Transaktion offen, wenn ein Fehler auftritt, und die Änderungen in der ersten Tabelle könnten gespeichert werden.
Geschichte
In einem Projekt für einen Online-Shop wurde die Fehlerbehandlung in Transaktionen vergessen, was zu einem teilweisen Verlust verknüpfter Daten führte: Wenn beim Aktualisieren einer Bestellung ein Problem mit der aktualisierten Bestandsmenge auftrat, wurden nur Teile der Änderungen zurückgesetzt, was die Informationsintegrität verletzte.
Geschichte
In einem BI-Analytics-Projekt wurde eine massenhafte Berichterstattung über eine Prozedur ohne explizite Kontrolle der Transaktionen und Fehlerbehandlung implementiert. Ergebnis: Ein Teil der Berichte wurde aktualisiert, der andere nicht. Die endgültigen Daten waren inkonsistent, da Notfälle nicht zu einer atomaren Rückgängigmachung führten.
Geschichte
In einem Unternehmen wurde fälschlicherweise auf autocommit in MySQL vertraut, ohne den Transaktionsmodus für große Operationen einzustellen. Bei einem Serverausfall waren einige Daten bereits gespeichert, andere nicht, was zu langen Wiederherstellungsarbeiten und dem Verlust eines Teils der Bestellungen führte.