SAVEPOINT Oracle : Gérer les points de sauvegarde SQL

Apprenez à utiliser SAVEPOINT en Oracle SQL pour contrôler vos transactions. Syntaxe, exemples pratiques et erreurs courantes expliqués clairement.

Illustration du tutoriel SQL Oracle : SAVEPOINT Oracle : Gérer les points de sauvegarde SQL

Publicité

🧪 Envie de pratiquer ? Exécutez les exemples de cet article dans notre SQL Playground gratuit — aucun logiciel à installer.

SAVEPOINT Oracle : Maîtriser les points de sauvegarde dans vos transactions SQL

Le SAVEPOINT est une instruction SQL Oracle qui permet de définir un point intermédiaire au sein d’une transaction. Grâce au SAVEPOINT, il devient possible d’annuler partiellement une transaction sans perdre l’intégralité des opérations effectuées. C’est un outil indispensable pour tout développeur ou DBA souhaitant gérer finement les transactions dans Oracle Database.

Définition et utilisation du SAVEPOINT Oracle

Dans Oracle, une transaction est un ensemble d’instructions DML (INSERT, UPDATE, DELETE) qui forment une unité logique de travail. Par défaut, un ROLLBACK annule toute la transaction en cours. C’est là qu’intervient le SAVEPOINT.

Un SAVEPOINT est un marqueur nommé posé à un instant précis dans la transaction. Il permet d’exécuter un ROLLBACK TO SAVEPOINT pour revenir à ce point précis, tout en conservant les modifications effectuées avant ce marqueur.

Cas d’usage en entreprise

  • Traitement par lots (batch) : lors d’un import massif de données, on pose un savepoint après chaque bloc de 1000 lignes. En cas d’erreur, seul le bloc courant est annulé.
  • Procédures stockées complexes : dans une procédure PL/SQL qui enchaîne plusieurs étapes métier (création commande, mise à jour stock, facturation), chaque étape peut être sécurisée par un savepoint.
  • Débogage transactionnel : pendant le développement, un développeur teste des modifications critiques sans risquer de corrompre l’ensemble de la transaction.

Il est important de noter que le SAVEPOINT n’est pas une validation définitive. Les données ne sont pas persistées tant qu’un COMMIT final n’est pas émis.

Syntaxe du SAVEPOINT Oracle

La syntaxe de l’instruction SAVEPOINT est volontairement simple :

SAVEPOINT nom_du_savepoint;

Pour revenir à un savepoint précédemment posé, on utilise :

ROLLBACK TO SAVEPOINT nom_du_savepoint;

Ou dans sa forme abrégée :

ROLLBACK TO nom_du_savepoint;

Explication des paramètres

  • nom_du_savepoint : identifiant libre choisi par le développeur. Il doit respecter les règles de nommage Oracle (pas d’espaces, pas de mots réservés). La longueur maximale est de 128 caractères depuis Oracle 12c (32 caractères dans les versions antérieures).
  • Si deux savepoints portent le même nom dans la même transaction, le second écrase le premier. Oracle ne génère pas d’erreur.
  • Un savepoint est automatiquement supprimé après un COMMIT ou un ROLLBACK complet.

Interaction avec COMMIT et ROLLBACK

InstructionEffet sur les savepoints
COMMITValide toute la transaction. Tous les savepoints sont effacés.
ROLLBACKAnnule toute la transaction. Tous les savepoints sont effacés.
ROLLBACK TO SAVEPOINTAnnule uniquement jusqu’au savepoint ciblé. Les savepoints postérieurs sont supprimés, les antérieurs restent actifs.

Exemples pratiques de SAVEPOINT Oracle

Exemple 1 — Gestion d’une commande client avec annulation partielle

Contexte métier : Un opérateur saisit une commande e-commerce. Il insère la commande, puis les lignes de commande. Une erreur survient sur la deuxième ligne. On souhaite annuler uniquement les lignes de commande, pas la commande principale.

-- Début implicite de la transaction

-- Étape 1 : Insertion de la commande principale
INSERT INTO commandes (id_commande, id_client, date_commande, statut)
VALUES (1001, 42, SYSDATE, 'EN_COURS');

-- Pose d'un savepoint après la commande principale
SAVEPOINT sp_commande_creee;

-- Étape 2 : Insertion des lignes de commande
INSERT INTO lignes_commande (id_ligne, id_commande, id_produit, quantite, prix_unitaire)
VALUES (1, 1001, 501, 2, 29.99);

INSERT INTO lignes_commande (id_ligne, id_commande, id_produit, quantite, prix_unitaire)
VALUES (2, 1001, 999, 1, -5.00); -- Prix négatif : erreur métier détectée !

-- On annule uniquement les lignes de commande, pas la commande elle-même
ROLLBACK TO SAVEPOINT sp_commande_creee;

-- La commande 1001 existe toujours, les lignes ont été annulées
-- On peut corriger et réinsérer les lignes proprement
INSERT INTO lignes_commande (id_ligne, id_commande, id_produit, quantite, prix_unitaire)
VALUES (1, 1001, 501, 2, 29.99);

INSERT INTO lignes_commande (id_ligne, id_commande, id_produit, quantite, prix_unitaire)
VALUES (2, 1001, 302, 1, 49.99); -- Produit corrigé

-- Validation définitive de l'ensemble de la transaction
COMMIT;

Exemple 2 — Traitement par lots avec savepoints multiples en PL/SQL

Contexte métier : Une banque met à jour les soldes de comptes clients par groupes de 500 enregistrements. En cas d’erreur sur un groupe, seul ce groupe est annulé.

DECLARE
  v_compteur NUMBER := 0;
  v_savepoint_name VARCHAR2(30);
BEGIN
  -- Boucle de traitement sur les comptes à mettre à jour
  FOR rec IN (SELECT id_compte, nouveau_solde FROM maj_soldes_temp ORDER BY id_compte) LOOP

    v_compteur := v_compteur + 1;

    -- Pose d'un savepoint tous les 500 enregistrements
    IF MOD(v_compteur, 500) = 1 THEN
      v_savepoint_name := 'SP_LOT_' || TO_CHAR(CEIL(v_compteur / 500));
      EXECUTE IMMEDIATE 'SAVEPOINT ' || v_savepoint_name;
    END IF;

    BEGIN
      -- Mise à jour du solde du compte
      UPDATE comptes_clients
      SET    solde = rec.nouveau_solde,
             date_maj = SYSDATE
      WHERE  id_compte = rec.id_compte;

    EXCEPTION
      WHEN OTHERS THEN
        -- En cas d'erreur, on annule le lot courant et on trace l'erreur
        EXECUTE IMMEDIATE 'ROLLBACK TO SAVEPOINT ' || v_savepoint_name;
        INSERT INTO log_erreurs (id_compte, message, date_erreur)
        VALUES (rec.id_compte, SQLERRM, SYSDATE);
    END;

  END LOOP;

  -- Validation finale de tous les lots traités avec succès
  COMMIT;

EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    RAISE;
END;
/
Publicité

Erreurs courantes avec SAVEPOINT Oracle

Erreur : ORA-01086 — Savepoint inexistant

Message Oracle : ORA-01086: savepoint 'NOM_SAVEPOINT' never established in this session or is invalid

Cause : Cette erreur survient lorsqu’on tente un ROLLBACK TO SAVEPOINT en référençant un nom de savepoint qui n’a pas été créé, a été mal orthographié, ou a été effacé suite à un COMMIT ou ROLLBACK complet antérieur.

Exemple déclenchant l’erreur :

INSERT INTO employes (id, nom) VALUES (99, 'Dupont');
SAVEPOINT sp_etape1;
COMMIT; -- Le savepoint sp_etape1 est détruit ici

-- Plus tard dans le code...
ROLLBACK TO SAVEPOINT sp_etape1; -- ORA-01086 : savepoint introuvable !

Solution : Vérifiez que le savepoint est bien posé après le dernier COMMIT ou ROLLBACK. En PL/SQL, utilisez une variable pour centraliser les noms de savepoints et éviter les fautes de frappe. N’oubliez pas qu’un COMMIT remet le compteur à zéro pour les savepoints.

Résumé

Tableau récapitulatif des points clés

ÉlémentDétail
InstructionSAVEPOINT nom
Retour au savepointROLLBACK TO SAVEPOINT nom
Longueur du nom128 caractères max (Oracle 12c+)
Durée de vieJusqu’au prochain COMMIT ou ROLLBACK complet
Doublon de nomLe second savepoint écrase le premier, sans erreur
VisibilitéSession courante uniquement
Erreur principaleORA-01086 si savepoint introuvable

Bonnes pratiques Oracle

  1. Nommez vos savepoints de façon explicite et cohérente : préférez des noms comme SP_APRES_INSERT_COMMANDE plutôt que SP1. En PL/SQL, centralisez ces noms dans des constantes pour éviter toute incohérence lors d’un ROLLBACK TO SAVEPOINT.
  2. Utilisez les savepoints en complément d’une gestion d’exceptions structurée : dans un bloc PL/SQL, combinez SAVEPOINT avec des blocs BEGIN...EXCEPTION...END imbriqués pour isoler les erreurs au niveau le plus fin, sans jamais laisser une transaction dans un état indéterminé.

Aller plus loin

Pour approfondir votre maîtrise des transactions Oracle, nous vous recommandons les sujets suivants :

Sur le même thème

Un nouveau tutoriel SQL par semaine

Nous ne spammons pas ! Consultez notre politique de confidentialité pour plus d’informations.

Publicité

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publicité