SQL COMMIT et SQL ROLLBACK

Par :

,le

La commande SQL COMMIT valide définitivement toutes les modifications effectuées depuis le début d’une transaction. La commande ROLLBACK les annule intégralement, comme si elles n’avaient jamais eu lieu. Ces deux commandes terminent toujours une transaction ouverte par BEGIN TRANSACTION.

COMMIT et ROLLBACK fonctionnent sur MySQL, MariaDB, PostgreSQL, SQL Server, SQLite et DB2. La syntaxe de base est identique sur tous ces systèmes. Seule la commande d’ouverture de transaction varie : BEGIN TRANSACTION sur SQL Server, BEGIN ou START TRANSACTION sur MySQL et PostgreSQL.

Syntaxe de base

BEGIN TRANSACTION ouvre la transaction et isole les modifications des autres utilisateurs. COMMIT les valide. ROLLBACK les annule en cas d’erreur.

-- Validation : COMMIT
BEGIN TRANSACTION;
INSERT INTO clients (nom, email) VALUES ('Dupont', 'dupont@email.com');
UPDATE clients SET actif = 1 WHERE nom = 'Dupont';
COMMIT;

Les deux opérations sont validées simultanément et deviennent visibles pour tous les utilisateurs connectés.

-- Annulation : ROLLBACK
BEGIN TRANSACTION;
INSERT INTO clients VALUES ('Martin', 'martin@email.com');
-- Erreur détectée
ROLLBACK;

ROLLBACK supprime l’insertion de Martin comme si elle n’avait jamais eu lieu. La base retrouve exactement son état antérieur au BEGIN.

COMMIT vs ROLLBACK

COMMIT et ROLLBACK produisent des effets opposés mais complémentaires sur une transaction.

PropriétéCOMMITROLLBACK
ActionValide toutes les modificationsAnnule toutes les modifications
Irréversible✅ Oui❌ Non (retour à l’état initial)
VisibilitéVisible par tous les utilisateursInvisible, jamais appliqué
DéclenchementFin de transaction réussieErreur ou abandon volontaire

Un COMMIT écrit les modifications sur disque de manière permanente : elles survivent aux redémarrages du serveur. Un ROLLBACK efface les traces mémoire des opérations depuis le dernier BEGIN.

Exemples pratiques

Virement bancaire

Un virement débite un compte et en crédite un autre. Ces deux opérations sont indissociables : l’une sans l’autre crée un déséquilibre comptable.

BEGIN TRANSACTION;
UPDATE comptes SET solde = solde - 500 WHERE id = 101;
UPDATE comptes SET solde = solde + 500 WHERE id = 202;
COMMIT;

COMMIT valide les deux mises à jour simultanément. Le total des soldes reste équilibré.

Si une erreur survient après le premier UPDATE, le ROLLBACK annule le débit du compte 101 :

BEGIN TRANSACTION;
UPDATE comptes SET solde = solde - 500 WHERE id = 101;
-- Erreur : compte 202 bloqué
ROLLBACK;

Le compte 101 retrouve son solde initial. Aucun euro n’est perdu.

Import de données en lot

Insérer plusieurs produits en une seule transaction garantit que l’import est complet ou qu’aucune ligne n’est enregistrée.

BEGIN TRANSACTION;
INSERT INTO produits (nom, prix) VALUES
    ('Ordinateur', 800),
    ('Souris', 25),
    ('Clavier', 60);
COMMIT;

Si l’insertion d’un produit échoue (contrainte violée, par exemple), ROLLBACK annule les insertions précédentes déjà effectuées dans la même transaction.

Synchronisation stock et commande

Décrémenter le stock et enregistrer la vente doivent former une unité indivisible pour éviter les incohérences entre les deux tables.

BEGIN TRANSACTION;
UPDATE produits SET stock = stock - 1 WHERE id = 50;
INSERT INTO commandes (client_id, produit_id) VALUES (123, 50);
COMMIT;

Si l’insertion dans commandes échoue, ROLLBACK restaure le stock à sa valeur initiale.

Autocommit : comportement par défaut

Par défaut, MySQL et MariaDB fonctionnent en mode autocommit activé : chaque requête est une transaction indépendante validée automatiquement. Ce mode convient aux modifications unitaires simples, mais pas aux séquences multi-requêtes.

SET autocommit = 1;  -- Mode par défaut MySQL
INSERT INTO clients VALUES ('Paul', 'paul@email.com');  -- COMMIT automatique
UPDATE clients SET actif = 1 WHERE nom = 'Paul';        -- COMMIT automatique

Chaque requête est validée immédiatement. Une erreur sur la deuxième laisse la première définitivement appliquée, sans possibilité de ROLLBACK.

Pour contrôler les validations manuellement, désactiver l’autocommit :

SET autocommit = 0;
INSERT INTO clients VALUES ('Marie', 'marie@email.com');
UPDATE clients SET actif = 1 WHERE nom = 'Marie';
COMMIT;  -- Les deux opérations sont validées ensemble

Avec autocommit = 0, toutes les modifications restent en attente jusqu’au COMMIT. Une erreur intermédiaire permet d’annuler l’ensemble avec ROLLBACK.

Gestion des erreurs avec TRY/CATCH

En production, encapsuler la transaction dans un bloc TRY/CATCH garantit qu’un ROLLBACK est toujours exécuté en cas d’erreur, même inattendue. Sans ce mécanisme, une transaction non terminée pose des verrous indéfinis sur les tables concernées.

Cette syntaxe est native à SQL Server. PostgreSQL et MySQL gèrent les erreurs côté application (PHP, Python, etc.).

BEGIN TRY
    BEGIN TRANSACTION;
    UPDATE comptes SET solde = solde - 1000 WHERE id = 101;
    UPDATE comptes SET solde = solde + 1000 WHERE id = 202;
    COMMIT;
END TRY
BEGIN CATCH
    ROLLBACK;
    PRINT 'Erreur : ' + ERROR_MESSAGE();
END CATCH;

Le bloc CATCH intercepte toute erreur SQL et exécute ROLLBACK systématiquement. Le message d’erreur facilite le diagnostic en production.

Bonnes pratiques

  • Toujours ouvrir avec BEGIN TRANSACTION avant une séquence de requêtes interdépendantes, pour isoler clairement le bloc transactionnel.
  • Encapsuler dans TRY/CATCH (SQL Server) ou gérer les erreurs côté application pour garantir un ROLLBACK systématique.
  • Désactiver l’autocommit (SET autocommit = 0) pour les processus métier multi-requêtes en MySQL.
  • Limiter la durée des transactions : une transaction longue pose des verrous qui bloquent les autres utilisateurs sur les tables modifiées.
  • Tester les chemins de ROLLBACK en préproduction en simulant des contraintes violées et des pannes réseau.

Erreurs courantes

Erreur 1 : oublier le ROLLBACK après une erreur

Une transaction laissée ouverte sans ROLLBACK pose des verrous qui bloquent les autres utilisateurs sur les tables modifiées.

-- ❌ Transaction ouverte sans ROLLBACK
BEGIN TRANSACTION;
UPDATE comptes SET solde = solde - 1000 WHERE id = 1;
-- Erreur réseau, pas de ROLLBACK → verrous actifs indéfiniment

-- ✅ Toujours fermer la transaction
BEGIN TRANSACTION;
UPDATE comptes SET solde = solde - 1000 WHERE id = 1;
ROLLBACK;  -- Libère immédiatement les verrous

Erreur 2 : laisser l’autocommit activé sur une séquence multi-requêtes

Avec autocommit = 1, chaque requête est validée individuellement. Une erreur sur la deuxième laisse la première définitivement appliquée.

-- ❌ Autocommit activé sur une séquence interdépendante
SET autocommit = 1;
INSERT INTO commandes VALUES (123, 50);  -- Validé immédiatement
UPDATE produits SET stock = stock - 1 WHERE id = 50;  -- Erreur → stock non décrémenté

-- ✅ Désactiver l'autocommit pour contrôler la validation
SET autocommit = 0;
INSERT INTO commandes VALUES (123, 50);
UPDATE produits SET stock = stock - 1 WHERE id = 50;
COMMIT;

Erreur 3 : tenter un ROLLBACK après un COMMIT

Une fois COMMIT exécuté, les modifications sont permanentes et ne peuvent plus être annulées par ROLLBACK.

-- ❌ ROLLBACK après COMMIT : sans effet
BEGIN TRANSACTION;
DELETE FROM logs WHERE date < '2025-01-01';
COMMIT;
ROLLBACK;  -- Trop tard, les données sont supprimées définitivement

-- ✅ Vérifier avant de valider
BEGIN TRANSACTION;
DELETE FROM logs WHERE date < '2025-01-01';
SELECT COUNT(*) FROM logs;  -- Vérifier le résultat avant COMMIT
COMMIT;

Sources

Sources: MySql , Postgresql , SQL Server