Skip to content
Retour au journal1 min de lecture

Publié le 6 mai 2025

Éviter la survente : le verrou pessimiste au moment de la commande

Comment garantir l'intégrité du stock sous commandes concurrentes dans une API NestJS + TypeORM, sans sacrifier la lisibilité.

NestJSTypeORMMySQLConcurrenceE-commerce

Deux clients achètent le dernier article exactement au même instant. Sans précaution, les deux commandes passent : vous venez de vendre un stock que vous n'avez pas. C'est le problème classique de la race condition sur le stock.

Pourquoi une simple vérification ne suffit pas

Lire le stock, vérifier qu'il est positif, puis décrémenter : entre la lecture et l'écriture, une autre transaction peut faire exactement la même chose. La vérification est déjà périmée quand on écrit.

Le verrou pessimiste

Au moment de la commande, je verrouille la ligne de stock pour la durée de la transaction. Toute autre transaction qui veut la même ligne attend son tour :

await dataSource.transaction(async (manager) => {
  const item = await manager.findOne(StockItem, {
    where: { id },
    lock: { mode: "pessimistic_write" },
  });

  if (!item || item.quantity < requested) {
    throw new ConflictException("Stock insuffisant");
  }

  item.quantity -= requested;
  await manager.save(item);
});

La lecture et l'écriture sont désormais atomiques du point de vue des autres transactions : la survente devient impossible.

Pessimiste plutôt qu'optimiste ?

Le verrouillage optimiste (numéro de version + réessai) brille quand les conflits sont rares. Sur une ligne de stock très convoitée, les conflits sont fréquents : le verrou pessimiste évite une avalanche de réessais et garde le code simple à lire. Le bon outil dépend du profil de contention.

Le coût

Un verrou sérialise l'accès à la ligne : à garder le plus court possible, et à ne poser que sur ce qui doit l'être. Dans une commande, c'est un compromis que j'assume volontiers contre la certitude de ne jamais survendre.

/ Contact

Un logiciel à concevoir, déployer, opérer ?

Écrivez-moi. Je réponds sous 48 h.