Leçon 13 / 20

Encadrer une opération par une transaction

20 min SQL — modélisation, index et optimisation Gratuit

Objectif : Regrouper la mise à jour de disponibilité d’un exemplaire et la création de l’emprunt dans une transaction atomique.

Si vous marquez un exemplaire comme indisponible puis que l’insertion de l’emprunt échoue, votre base conserve un état incohérent. À l’inverse, enregistrer l’emprunt sans réserver l’exemplaire permettrait de le prêter une seconde fois. Une transaction regroupe ces écritures pour que l’opération métier soit validée entièrement ou annulée entièrement.

Ce que garantit une transaction

Une transaction SQL est une unité de travail composée d’une ou plusieurs instructions. Avec InnoDB, vous démarrez cette unité par START TRANSACTION, puis vous la terminez en validant ses changements avec COMMIT ou en les annulant avec ROLLBACK. Tant qu’elle n’est pas validée, ses modifications restent dans la transaction en cours ; ne les considérez pas comme acquises.

La propriété ACID résume les garanties recherchées : atomicité, cohérence, isolation et durabilité. Ici, concentrez-vous sur l’atomicité : la réservation de l’exemplaire et la création de l’emprunt forment un seul tout. Les autres propriétés interviennent aussi dans le comportement global d’une base transactionnelle, mais l’isolation et la gestion des accès concurrents seront étudiées dans les prochaines leçons.

Créer un emprunt dans une transaction

Le modèle du projet utilise les tables exemplaires et emprunts, avec les identifiants exemplaire_id et adherent_id. Pour rendre l’exemple exécutable sans supposer une colonne de disponibilité qui n’est pas définie par le contrat, la réservation est représentée ici par une ligne dans emprunts. Une valeur date_retour à NULL signale que le prêt est encore en cours ; la date prévue est fixée à quatorze jours après l’emprunt.

sql/transactions.sql — valider un prêtSQL
-- Réserver l’exemplaire et créer l’emprunt dans une seule transaction.
-- Les deux identifiants doivent correspondre à des lignes existantes.
START TRANSACTION;

INSERT INTO emprunts (
    adherent_id,
    exemplaire_id,
    date_emprunt,
    date_retour_prevue,
    date_retour
)
VALUES (
    42,
    105,
    CURRENT_DATE,
    DATE_ADD(CURRENT_DATE, INTERVAL 14 DAY),
    NULL
);

-- La réservation et l’emprunt sont validés ensemble.
COMMIT;

Si l’insertion réussit et que COMMIT est exécuté, la ligne d’emprunt devient une partie validée de l’historique. Si une règle d’intégrité rejette l’insertion, par exemple parce qu’un adhérent ou un exemplaire référencé n’existe pas, vous devez annuler la transaction avant de poursuivre. Dans une application, le code doit également gérer les erreurs de connexion et confirmer explicitement le résultat de la transaction.

Annuler une opération incomplète

La transaction devient utile lorsqu’une opération comporte plusieurs écritures. Dans l’exemple suivant, vous enregistrez l’emprunt puis créez son retard associé ; si cette seconde écriture échoue, ROLLBACK annule aussi l’emprunt. La table retards est rattachée à l’emprunt : le test porte sur une valeur de retard initiale et ne remplace pas les règles de calcul ou d’actualisation documentées ailleurs dans le projet.

sql/transactions.sql — annuler si une étape échoueSQL
-- Exemple pédagogique : en cas d’erreur après la première écriture,
-- exécutez ROLLBACK au lieu de COMMIT.
START TRANSACTION;

INSERT INTO emprunts (
    adherent_id,
    exemplaire_id,
    date_emprunt,
    date_retour_prevue,
    date_retour
)
VALUES (
    42,
    105,
    CURRENT_DATE,
    DATE_ADD(CURRENT_DATE, INTERVAL 14 DAY),
    NULL
);

-- Dans une session MariaDB, récupérez l’identifiant généré juste après
-- l’INSERT, puis remplacez 9001 par cette valeur.
INSERT INTO retards (
    emprunt_id,
    jours_retard
)
VALUES (
    9001,
    0
);

-- Si la seconde étape échoue, n’exécutez pas COMMIT.
ROLLBACK;
Résultat attendu
Après ROLLBACK, les écritures de cette transaction ne sont pas conservées. En production, le programme exécute ROLLBACK dans son traitement d’erreur et utilise l’identifiant effectivement généré, au lieu de la valeur illustrative 9001.

À retenir

  • Démarrez l’unité de travail avec START TRANSACTION.
  • Utilisez COMMIT uniquement lorsque toutes les étapes de l’opération métier ont réussi.
  • Utilisez ROLLBACK pour annuler les écritures lorsque l’opération échoue en cours de route.
  • Vérifiez que les tables concernées utilisent InnoDB et évitez toute validation intermédiaire.

La prochaine leçon compare les niveaux d’isolation et précise les comportements que vous pouvez attendre lorsque plusieurs sessions travaillent simultanément.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.