La commande SQL SAVEPOINT crée un point de restauration intermédiaire à l’intérieur d’une transaction active. Elle permet d’annuler partiellement des modifications sans abandonner toute la transaction. Les commandes associées sont ROLLBACK TO SAVEPOINT pour revenir au point créé et RELEASE SAVEPOINT pour le supprimer.
SAVEPOINT fonctionne sur MySQL (moteur InnoDB uniquement), PostgreSQL et MariaDB avec la syntaxe standard. SQL Server utilise une syntaxe différente : SAVE TRANSACTION. La commande n’est disponible qu’à l’intérieur d’une transaction ouverte avec BEGIN ou START TRANSACTION.
Il est possible d’utiliser les principales commandes SQL telles que SELECT, INSERT, UPDATE et DELETE que ce soit sur des outils graphiques comme Phpmyadmin, pgAdmin ou en ligne de commande quel que soit le SGBD.
Table des matières
Syntaxe de base
Trois commandes forment le cycle complet d’un savepoint : création, annulation partielle et suppression. Chaque commande prend le nom du savepoint comme argument.
-- Créer un savepoint
SAVEPOINT nom_savepoint;
-- Revenir à ce savepoint (annule les modifications postérieures)
ROLLBACK TO SAVEPOINT nom_savepoint;
-- Supprimer le savepoint (libère les ressources associées)
RELEASE SAVEPOINT nom_savepoint;
ROLLBACK TO SAVEPOINT annule uniquement les opérations effectuées après la création du savepoint. La transaction reste ouverte : les opérations suivantes et le COMMIT final restent nécessaires.
Utiliser SAVEPOINT dans une transaction
SAVEPOINT s’utilise exclusivement à l’intérieur d’une transaction active. Il mémorise l’état exact des données à l’instant de sa création. Les opérations suivantes peuvent être annulées jusqu’à ce point sans toucher aux opérations précédentes.
Pour créer un point de restauration après une première opération réussie, puis annuler uniquement la seconde en cas d’erreur :
START TRANSACTION;
INSERT INTO commandes (client_id, total) VALUES (123, 150.00);
SAVEPOINT apres_commande;
UPDATE stock SET quantite = quantite - 2 WHERE sku = 'ABC123';
SAVEPOINT apres_stock;
-- Erreur détectée sur l'étape suivante
UPDATE stock SET quantite = quantite - 1 WHERE sku = 'DEF456';
ROLLBACK TO SAVEPOINT apres_stock;
COMMIT;
Après ROLLBACK TO SAVEPOINT apres_stock, la commande et la mise à jour du stock ABC123 sont conservées. Seule la mise à jour de DEF456 est annulée. Le COMMIT final valide les deux opérations préservées.
ROLLBACK TO SAVEPOINT en détail
ROLLBACK TO SAVEPOINT annule toutes les opérations effectuées après la création du savepoint ciblé. La transaction reste ouverte après cette commande : il faut obligatoirement terminer avec COMMIT ou ROLLBACK total.
Ne pas terminer la transaction après un ROLLBACK TO SAVEPOINT laisse les verrous actifs sur les tables modifiées et bloque les autres utilisateurs.
START TRANSACTION;
SAVEPOINT etape1;
UPDATE produits SET prix = prix * 1.10 WHERE categorie = 'electronique';
SAVEPOINT etape2;
DELETE FROM produits WHERE stock = 0;
-- Erreur : suppression non souhaitée
ROLLBACK TO SAVEPOINT etape2;
-- La mise à jour des prix est conservée, la suppression est annulée
COMMIT;
Après ROLLBACK TO SAVEPOINT etape2, la mise à jour des prix reste active. COMMIT la valide définitivement.
RELEASE SAVEPOINT
RELEASE SAVEPOINT supprime un savepoint et libère les ressources système associées. Le savepoint devient inutilisable après cette commande. Les données ne sont pas modifiées par cette opération.
RELEASE SAVEPOINT est utile dans les transactions longues avec de nombreux savepoints pour libérer la mémoire au fur et à mesure.
START TRANSACTION;
SAVEPOINT avant_import;
INSERT INTO produits (nom, prix) VALUES ('Ordinateur', 800);
-- Insertion réussie, le savepoint n'est plus nécessaire
RELEASE SAVEPOINT avant_import;
INSERT INTO produits (nom, prix) VALUES ('Souris', 25);
COMMIT;
Après RELEASE SAVEPOINT, revenir à avant_import avec ROLLBACK TO SAVEPOINT n’est plus possible.
Compatibilité selon les SGBD
La syntaxe standard SAVEPOINT est disponible sur MySQL (InnoDB), PostgreSQL et MariaDB. SQL Server utilise une syntaxe différente avec SAVE TRANSACTION.
| Fonctionnalité | MySQL 8.4 (InnoDB) | PostgreSQL 18 | SQL Server |
|---|---|---|---|
| Syntaxe | SAVEPOINT nom | SAVEPOINT nom | SAVE TRANSACTION nom |
| Noms dupliqués | Remplace l’ancien | Conserve les deux | Remplace l’ancien |
| Limite d’imbrication | Pas de limite documentée | Pas de limite documentée | 32 caractères par nom |
| Procédures stockées | ✅ Supporté | ❌ Non supporté en PL/pgSQL | ✅ Supporté |
MySQL
MySQL supporte SAVEPOINT uniquement avec le moteur InnoDB. Le moteur MyISAM ne supporte pas les transactions et ignore les savepoints.
START TRANSACTION;
SAVEPOINT mysql_sp1;
UPDATE clients SET actif = 0 WHERE derniere_connexion < '2024-01-01';
ROLLBACK TO SAVEPOINT mysql_sp1;
COMMIT;
PostgreSQL
PostgreSQL supporte SAVEPOINT dans les transactions standards. En revanche, les procédures stockées PL/pgSQL gèrent les transactions différemment et ne supportent pas SAVEPOINT de la même façon.
BEGIN;
SAVEPOINT pg_sp1;
INSERT INTO ventes (produit_id, montant) VALUES (45, 120.00);
ROLLBACK TO SAVEPOINT pg_sp1;
COMMIT;
SQL Server
SQL Server utilise SAVE TRANSACTION à la place de SAVEPOINT. La fonctionnalité est équivalente. Les noms de savepoint sont limités à 32 caractères et sont toujours sensibles à la casse.
BEGIN TRANSACTION;
SAVE TRANSACTION sp_avant_update;
UPDATE produits SET prix = prix * 1.05 WHERE categorie = 'electronique';
ROLLBACK TRANSACTION sp_avant_update;
COMMIT TRANSACTION;
Cas pratique : commande e-commerce avec rupture de stock
Un client commande trois produits dont un en rupture de stock. SAVEPOINT permet de valider les deux produits disponibles et d’annuler uniquement le troisième.
START TRANSACTION;
INSERT INTO commandes (client_id, total) VALUES (123, 885.00);
SAVEPOINT apres_commande;
UPDATE stock SET quantite = quantite - 1 WHERE sku = 'ABC123'; -- OK
SAVEPOINT apres_abc;
UPDATE stock SET quantite = quantite - 1 WHERE sku = 'DEF456'; -- OK
SAVEPOINT apres_def;
UPDATE stock SET quantite = quantite - 1 WHERE sku = 'GHI789'; -- Rupture
ROLLBACK TO SAVEPOINT apres_def;
COMMIT; -- Commande + ABC123 + DEF456 validés
La commande est créée avec deux produits sur trois. Le troisième est annulé sans affecter les étapes précédentes.
Erreurs courantes
Erreur 1 : utiliser SAVEPOINT hors d’une transaction
SAVEPOINT échoue si aucune transaction n’est active au moment de son exécution.
-- ❌ Sans transaction active
SAVEPOINT sp1;
-- Erreur : aucune transaction en cours
-- ✅ Toujours ouvrir une transaction avant
START TRANSACTION;
SAVEPOINT sp1;
Erreur 2 : oublier le COMMIT après ROLLBACK TO SAVEPOINT
ROLLBACK TO SAVEPOINT ne termine pas la transaction. Sans COMMIT ou ROLLBACK final, les verrous restent actifs et bloquent les autres utilisateurs.
-- ❌ Transaction laissée ouverte
START TRANSACTION;
SAVEPOINT sp1;
UPDATE clients SET actif = 0 WHERE id = 5;
ROLLBACK TO SAVEPOINT sp1;
-- Pas de COMMIT → verrous indéfinis
-- ✅ Toujours terminer la transaction
ROLLBACK TO SAVEPOINT sp1;
COMMIT;
Erreur 3 : utiliser SAVEPOINT avec MyISAM en MySQL
MyISAM ne supporte pas les transactions. Les savepoints sont ignorés silencieusement sans message d’erreur.
-- ❌ Sur une table MyISAM : SAVEPOINT ignoré sans erreur
START TRANSACTION;
SAVEPOINT sp1;
INSERT INTO logs_myisam VALUES ('test');
ROLLBACK TO SAVEPOINT sp1; -- Sans effet, l'insertion est permanente
-- ✅ Vérifier le moteur de la table
SHOW TABLE STATUS WHERE Name = 'logs_myisam';
-- Engine doit être InnoDB pour que SAVEPOINT fonctionne
Sources: MySql , SQL Server, ANSI