Come evitare che due persone acquistino l'ultimo biglietto?
Share

In this article
- 01Perché una lettura seguita da scrittura sul conteggio dei biglietti può causare overselling?
- 02Perché usare un lock pessimista sulla riga per gli ultimi biglietti?
- 03Come fa una prenotazione in Redis a evitare che i checkout abbandonati blocchino l'inventario?
- 04Cosa succede se il webhook di pagamento arriva due volte?
- 05Regge sotto carico?
Decrementa il conteggio dei biglietti all'interno di una breve transazione di database che mantiene un lock pessimista sulla riga, e riserva ogni biglietto in Redis con un tempo di vita (TTL). La scrittura del secondo acquirente attende qualche millisecondo dietro la prima, poi vede che i biglietti sono esauriti. I checkout abbandonati rilasciano automaticamente la loro prenotazione quando il TTL scade.
Perché una lettura seguita da scrittura sul conteggio dei biglietti può causare overselling?
Due richieste possono leggere lo stesso conteggio residuo di uno, entrambe superano il controllo e entrambe registrano una vendita. Il conteggio era corretto al momento della lettura ma obsoleto al momento della scrittura, quindi un biglietto viene venduto due volte. Qualsiasi operazione di lettura seguita da scrittura su un inventario condiviso presenta questa gara a meno che la scrittura non sia atomica o bloccata.
Un semplice retry ottimistico risolve il problema di correttezza ma inizia a creare problemi quando gli ultimi biglietti di un evento popolare sono colpiti da un picco di checkout: ogni client dell'acquirente perdente deve ripetere l'intero processo di checkout, non solo la scrittura.
Perché usare un lock pessimista sulla riga per gli ultimi biglietti?
Un lock pessimista fa sì che il secondo scrittore attenda brevemente invece di fallire e riprovare alla cieca. Per una riga molto richiesta da molti acquirenti contemporaneamente, qualche millisecondo di attesa è meno costoso rispetto a ripetere l'intero checkout. Il lock viene mantenuto solo per la breve transazione che decrementa il conteggio dei biglietti.
Come fa una prenotazione in Redis a evitare che i checkout abbandonati blocchino l'inventario?
Quando un acquirente inizia il checkout, si riserva il biglietto in Redis con un TTL. Se paga, la prenotazione si converte in vendita. Se abbandona, la chiave scade e il biglietto torna automaticamente disponibile nell'inventario. Nessuno può tenere un biglietto in ostaggio aprendo una scheda di checkout e poi allontanandosi.
Cosa succede se il webhook di pagamento arriva due volte?
Niente di speciale. Il gestore del webhook è idempotente, basato sull'ID dell'ordine, e il suo unico compito è pubblicare un evento di pagamento confermato su RabbitMQ. Una consegna ripetuta trova l'ordine già gestito, quindi un biglietto non viene mai emesso due volte. Un consumatore a valle genera il biglietto e invia la conferma.
Lo stesso schema è spiegato passo passo nella nota sui webhook idempotenti.
Regge sotto carico?
Nei test su FindYourVibe, il checkout è rimasto corretto con oltre 300 acquirenti concorrenti su un singolo rilascio di evento, senza overselling di biglietti. Le scelte progettuali che hanno permesso questo sono il lock pessimista sulle ultime righe, la prenotazione Redis con TTL e il webhook idempotente che alimenta una coda.
Lock pessimista sulla riga per gli ultimi biglietti di un evento
Prenotazione in Redis con TTL, per evitare overselling
RabbitMQ disaccoppia l'emissione del biglietto dalla risposta del webhook
Webhook di pagamento idempotente basato sull'ID dell'ordine
Originariamente pubblicato su sakshamjain.codes/blog/stop-two-people-buying-the-last-ticket. Hai bisogno di questo sistema? Vedi i miei servizi su NexoRush o contattami.