Comment empêcher deux personnes d'acheter le dernier billet ?
Share

In this article
- 01Pourquoi une lecture puis écriture sur le nombre de billets entraîne-t-elle une survente ?
- 02Pourquoi utiliser un verrou pessimiste sur la ligne pour les derniers billets ?
- 03Comment une réservation dans Redis empêche-t-elle les validations abandonnées de bloquer l'inventaire ?
- 04Que se passe-t-il si le webhook de paiement arrive deux fois ?
- 05Est-ce fiable sous forte charge ?
Décrémentez le nombre de billets dans une courte transaction de base de données qui maintient un verrou pessimiste sur la ligne, et réservez chaque billet dans Redis avec un temps de vie (TTL). L'écriture du deuxième acheteur attend quelques millisecondes derrière la première, puis constate que c'est complet. Les réservations abandonnées sont automatiquement libérées lorsque le TTL expire.
Pourquoi une lecture puis écriture sur le nombre de billets entraîne-t-elle une survente ?
Deux requêtes peuvent lire le même nombre restant d'un billet, toutes deux passent la vérification, et toutes deux enregistrent une vente. Le nombre était correct lors de la lecture mais obsolète lors de l'écriture, donc un billet est vendu deux fois. Toute opération lecture-puis-écriture sur un inventaire partagé présente cette course à moins que l'écriture ne soit atomique ou verrouillée.
Une simple tentative optimiste corrige le problème de cohérence mais provoque des répétitions excessives dès que les derniers billets d'un événement populaire sont sollicités par un afflux de validations : chaque client perdant doit recommencer tout le processus de validation, pas seulement l'écriture.
Pourquoi utiliser un verrou pessimiste sur la ligne pour les derniers billets ?
Un verrou pessimiste fait attendre brièvement le deuxième écrivain au lieu d'échouer et de retenter aveuglément. Pour une ligne très sollicitée par plusieurs acheteurs simultanés, quelques millisecondes d'attente coûtent moins cher que de recommencer tout le processus de validation. Le verrou est maintenu uniquement pendant la courte transaction qui décrémente le nombre de billets.
Comment une réservation dans Redis empêche-t-elle les validations abandonnées de bloquer l'inventaire ?
Quand un acheteur commence la validation, le billet est réservé dans Redis avec un TTL. S'il paie, la réservation devient une vente. S'il abandonne, la clé expire et le billet revient automatiquement dans l'inventaire. Personne ne peut bloquer un billet en ouvrant un onglet de validation puis en s'en allant.
Que se passe-t-il si le webhook de paiement arrive deux fois ?
Rien de spécial. Le gestionnaire de webhook est idempotent, identifié par l'ID de commande, et sa seule tâche est de publier un événement de paiement confirmé dans RabbitMQ. Une livraison répétée trouve la commande déjà traitée, donc un billet n'est jamais émis deux fois. Un consommateur en aval génère le billet et envoie la confirmation.
Le même schéma est expliqué étape par étape dans la note sur les webhooks idempotents.
Est-ce fiable sous forte charge ?
Lors des tests sur FindYourVibe, la validation est restée correcte avec plus de 300 acheteurs concurrents sur une seule mise en vente, sans survente de billet. Les choix de conception qui ont permis cela sont le verrou sur les derniers billets, la réservation Redis avec TTL, et le webhook idempotent alimentant une file d'attente.
Verrou pessimiste sur les dernières lignes de billets d'un événement
Réservation Redis avec TTL, évitant la survente
RabbitMQ découple l'émission des billets de la réponse du webhook
Webhook de paiement idempotent identifié par l'ID de commande
Publié à l'origine sur sakshamjain.codes/blog/stop-two-people-buying-the-last-ticket. Besoin de cette solution ? Découvrez mes services sur NexoRush ou contactez-moi.