En SQL, lors de modifications massives, il est souvent nécessaire de mettre en œuvre le scénario « tout ou rien » — soit toutes les modifications sont validées, soit elles sont annulées en cas d'erreur. Cette approche est atteinte grâce à l'utilisation de transactions. La procédure stockée doit explicitement démarrer une transaction (BEGIN TRANSACTION), envelopper les opérations correspondantes, gérer les erreurs et, en cas d'échec, exécuter ROLLBACK, sinon — COMMIT.
Il ne faut pas oublier la gestion correcte des erreurs via des constructions comme TRY...CATCH (SQL Server) ou EXCEPTION (PostgreSQL).
Exemple pour 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; -- Journalisation de l'erreur THROW; END CATCH END
Question: Est-il suffisant d'utiliser uniquement BEGIN TRANSACTION et COMMIT pour garantir un retour en arrière correct des modifications en cas d'erreurs dans tous les SGBD pris en charge ?
Réponse: Non, la transaction elle-même ne capture pas les exceptions. Il est nécessaire d'utiliser des gestionnaires (TRY...CATCH ou similaires) pour intercepter l'erreur et appeler explicitement ROLLBACK. Dans certains SGBD (par exemple, MySQL avec autocommit), un réglage supplémentaire peut également être nécessaire.
Exemple de code incorrect (SQL Server):
BEGIN TRANSACTION; UPDATE Users SET Name = 'Ivan' WHERE ID = 1; UPDATE Orders SET Amount = Amount/0 WHERE UserID = 1; -- Erreur de division par 0 COMMIT TRANSACTION;
Dans ce cas, si une erreur survient, la transaction restera ouverte et les modifications dans la première table pourraient être conservées.
Histoire
Dans le projet de la boutique en ligne, la gestion des erreurs dans les transactions a été omise, ce qui a entraîné une perte partielle de données liées : si un problème survenait lors de la mise à jour d'une commande et de l'actualisation des stocks, seules certaines modifications étaient annulées, compromettant ainsi l'intégrité des informations.
Histoire
Dans le projet d'analyse BI, un recalcul massif des rapports a été mis en œuvre via une procédure sans contrôle explicite des transactions et gestion des erreurs. Résultat : certaines rapports ont été mis à jour, d'autres non. Les données finales se sont avérées inconsistantes, car les situations d'urgence n'ont pas conduit à une annulation atomique.
Histoire
Dans une entreprise, on comptait à tort sur autocommit dans MySQL, sans avoir défini le mode de transactions pour les opérations de grande envergure. En cas de panne du serveur, certaines données avaient déjà été enregistrées, d'autres non, ce qui a entraîné de longs travaux de rétablissement et une perte partielle de commandes.