Définition
Une transaction logique est une unité de travail au niveau de l’application qui peut s’étendre sur plusieurs transactions physiques (base de données). En d’autres termes c’est un cas métier complet et logiquement transactionnel mais qui sera exécuté par plusieurs transactions physiques
Exemple 1

-
Alice demande l’affichage d’un produit.
-
Le produit est récupéré dans la base de données et renvoyé au navigateur.
-
Alice demande une modification du produit.
-
Comme Alice n’a pas conservé de copie de l’objet précédemment affiché, elle doit le recharger une nouvelle fois.
-
Le produit est mis à jour et enregistré dans la base de données.
-
La mise à jour du traitement par lots a été perdue et Alice ne s’en rendra jamais compte.
Étant donné que la transaction logique Alice englobe deux requêtes Web distinctes, chacune étant associée à une transaction de base de données distincte, sans mécanisme de contrôle de concurrence supplémentaire, même le niveau d’isolation le plus élevé (i.e SERIALIZABLE) ne peut empêcher le phénomène de perte de mise à jour.
Limite des niveaux d’isolation
Le niveau d’isolation — y compris SERIALIZABLE — ne garantit la cohérence qu’à l’intérieur d’une transaction unique. Dès lors qu’une logique métier s’étend sur plusieurs transactions :
- L’isolation ne peut plus empêcher les modifications concurrentes
- Les hypothèses faites lors de la première lecture peuvent devenir invalides
- La cohérence métier n’est plus garantie automatiquement
Si on reprend le schéma du dessus, avec des transaction de niveau SERIALIZABLE, nous voyons bien que les verrous ne servent à rien
GET product/1
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT stock FROM produit WHERE id = 1;
COMMIT; -- fermeture de la transaction-
Un batch UPDATE , mais comme la transaction 1 est finie il nʼy a pas de verrou. Le batch UPDATE et commit sans aucun problème
-
POST GET product/1/buyouverture dʼune nouvelle transaction
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
UPDATE produit SET stock = stock - 1 WHERE id = 1;
COMMIT;Exemple 2
Un autre exemple, pour illustrer ce même problème

- Les deux utilisateurs ont vu le même état initial “OPEN”, mais ont pris deux décisions opposées.
- Ils agissent dans deux transactions indépendantes, peut-être même en SERIALIZABLE.
- Comme chaque UPDATE est valide individuellement, la base les accepte.
- Le dernier commit gagne → lʼautre modification est écrasée sans alerte.
Affirmation
SERIALIZABLE fonctionne tant que la logique métier est contenue dans une seule transaction. Dès qu’elle est fragmentée dans le temps et entre plusieurs transactions, le niveau d’isolation ne suffit plus à assurer une logique transactionnelle correcte.
Solution
Pushing database transaction boundaries into the application layer requires an application-level concurrency control. To ensure application-level repeatable reads we need to preserve state across multiple user requests, but in the absence of database locking, we need to rely on an application-level concurrency control. 1
Une solution consiste à déléguer le travail à la couche applicative, par exemple
- en faisant du Pessimistic Locking (app stateful).
- ou en faisant du Optimistic locking (app stateless).