In che modo un sistema di prenotazione dei posti nei cinema impedisce a più utenti di prenotare gli stessi posti?


34

Nel cinema vado a hanno chioschi biglietti che ti permettono di selezionare i posti che desideri; hanno anche un sito Web che fa lo stesso (il sito Web ha anche un conto alla rovescia di circa 30 secondi in cui è necessario scegliere un posto).

Mentre capisco cose come le transazioni del database e altre tecniche per gestire più utenti simultanei, non riesco proprio a capire come è possibile consentire a più persone di selezionare un posto contemporaneamente; è semplice come il primo a premere ACQUISTA ottiene i posti e l'altra persona riceverà un messaggio di errore o mi sto perdendo qualcosa?


10
"è semplice come il primo a premere ACQUISTA ottiene i posti e l'altra persona riceverà un messaggio di errore". Quella.
yannis,

2
Sì, probabilmente, in una giornata burrascosa con una dozzina di macchine sembra che sarebbe un dolore però.
mbwasi,

2
Forse, ma tieni presente che gli utenti trascorreranno la maggior parte del loro tempo su altri schermi (inserendo i dettagli di pagamento, aspettando la stampa dei biglietti, ecc.), Quindi non tutti prenderanno posto contemporaneamente, e non ognuno ha le stesse preferenze di posto, quindi anche chi sceglie contemporaneamente sceglierà posti diversi. Non mi aspetto che ci siano così tante collisioni.
Dave Sherohman,

2
@JimG. Per ogni possibile soluzione, se entrambi i clienti premono acquista nello stesso momento (al millisecondo) uno verrà servito e l'altro riceverà una sorta di messaggio di errore. Esistono modi meravigliosi per ridurre al minimo le possibilità che ciò accada (tecnico e concettuale, come spiegato nelle risposte) ma nella straordinaria situazione in cui si verifica una richiesta verrà soddisfatta e l'altra fallirà. Così semplice.
yannis,

3
@JimG. Non è un tipo di comportamento. La concorrenza funziona fino a un certo punto, se entrambe le richieste raggiungono esattamente lo stesso microtime, si fallirà. Ovviamente puoi costruire un bel messaggio di errore attorno a quello, come nel commento di Hand-E-Food, ma il fatto rimane: è semplice come servire una richiesta e fallire l'altra. Non sto dicendo che non dovresti fare tutto per assicurarti che il fallimento sia il più semplice possibile per l'utente o che non dovresti proteggerlo.
yannis,

Risposte:


27

Il metodo classico per fare questo è usare un database transazionale (quindi non ci sono scontri) e fare un'allocazione provvisoria del posto che scade dopo un certo periodo di tempo (ad esempio, 10 minuti per i chioschi) che ti dà abbastanza tempo per pagare. Se la transazione (visibile al cliente) fallisce o scade, l'allocazione dei posti può essere rilasciata nuovamente nel pool. (Tutte le modifiche allo stato vengono elaborate tramite il database transazionale e una transazione visibile al cliente potrebbe richiedere molte transazioni a livello di database.)

Le compagnie aeree useranno un sistema simile (anche se molto più complesso a causa della necessità di gestire più tratte di volo!) Per prenotare posti online. Immagino che il timeout sarebbe notevolmente più lungo; i biglietti aerei sono generalmente prenotati in anticipo rispetto ai biglietti del cinema e sono anche più costosi.


Intendiamoci, il mio cinema locale in realtà non assegna posti normalmente. Al contrario, hanno provveduto a un eccessivo provisioning dei posti in modo che le persone potessero semplicemente alzarsi con il minimo sforzo. È una tecnica diversa, ma non pertinente alla tua domanda!
Donal Fellows,

Simile a scegliere posti per eventi sportivi. Ottieni il tuo numero N di posti riservati per 3 minuti mentre decidi se li desideri effettivamente e completi il ​​pagamento.
AndyMcKenna,

Si noti che esistono due diversi processi con, ad esempio, l'acquisto di posti aerei: in primo luogo, si acquista un biglietto senza un posto assegnato. In secondo luogo, quando si ottiene la carta d'imbarco (o se si effettua il check-in online), si ottiene un posto. Il numero di biglietti è in realtà ipervenduto perché sanno che, in media, un determinato numero non si presenta per il volo. L'assegnazione dei posti, tuttavia, sembra funzionare assegnandoti a caso un posto (primo arrivato, primo servito) al momento del check-in, e quindi consentendoti di cambiare il posto selezionandone uno disponibile, quindi effettuando il trasferimento in un'unica transazione .
Scott Whitlock,

2
@DonalFellows potresti spiegare un po 'di più la parte provvisoria di allocazione? Intendi prenotare alcuni posti per un utente per un certo periodo di tempo? Sto ancora cercando di capire le sfide che devono affrontare questo tipo di sistema.
Sandeepan Nath,

1
@SandeepanNath Non correttamente in un commento, ma il principio è banale. Il seggio viene posto in uno stato "assegnato in modo provvisorio" e il timeout di quello stato viene annotato contemporaneamente. Se la prenotazione è completata, il posto diventa completamente assegnato. In caso contrario e il timeout è raggiunto, il posto viene (eventualmente) spostato indietro nella piscina principale. (Inoltre, se l'utente annulla esplicitamente, il posto viene spostato direttamente nella piscina. Non c'è bisogno di aspettare.)
Donal Fellows

4

I 30 secondi che hai visto oggi sono spesso più simili a 15 minuti. Non credo che ci sia una transazione di database attiva per quella durata.

Se dovessi progettare un tale sistema, è così che lo farei: avere gli oggetti business Bookinge Reservation. Le prenotazioni sono essenzialmente confermate (ovvero pagate). Li memorizzerei nella stessa tabella DB e li distinguerei per uno o due attributi.

Quando recuperi posti disponibili, dovresti interrogare sia le prenotazioni che le prenotazioni.

Quando qualcuno seleziona un posto, si crea una nuova prenotazione, mostrando così ad altri clienti il ​​posto come occupato. Una seconda prenotazione per lo stesso posto verrà rifiutata: l'aggiornamento o l'inserimento del DB falliranno. Se il cliente conferma / paga per la prenotazione, la si passa a una prenotazione. In un processo batch periodico elimini tutte le prenotazioni di età superiore a 15 minuti (o in qualsiasi momento dai ai tuoi clienti).



1

Ci sono almeno 2 processi aziendali coinvolti qui.

  • Processo uno:

Mostra posti disponibili.

  • Processo due:

Prenota un posto selezionato.

Poiché questi processi non si susseguono immodificamente e poiché 2 persone possono selezionare lo stesso posto, sorge il problema della concorrenza.

Se la progettazione del database assegna il vincolo di unicità corretto in modo che la combinazione di:

-TheaterID

-SeatID

-EventID

sono univoci, quindi il database eviterà i duplicati.

È anche possibile il seguente scenario, ma sarà curato dall'implementazione suggerita sopra:

Supponendo che una vista a griglia sia disponibile per un determinato teatro e un determinato evento possano essere visualizzati:

  1. Utente1 visualizza i posti disponibili (e ottiene i posti 1 e 2)
  2. Utente2 visualizza i posti disponibili (e ottiene i posti 1 e 2)
  3. Utente1 parla un po 'con il cliente al telefono
  4. Utente2 va e prenota il posto 2 per il suo cliente
  5. L'utente1 tenta di prenotare il posto 2 per il suo cliente (perché mostra come disponibile sul suo schermo)
  6. L'indice univoco impedisce al passaggio 5 di commutare i dati.

Quindi tutto ciò che devi fare potrebbe essere niente più corretta progettazione del database e scelta corretta sui vincoli.

Altri approcci più complessi sono possibili se lo si desidera, utilizzando le code delle transazioni. In questo caso, le richieste vengono scritte prima in una coda, quindi avvia un processo ogni n secondi, ma nel tuo caso non è quasi necessario o pratico.

La parte davvero interessante è cosa dovrebbe mostrare la griglia dell'elenco per l'utente 1?


1

Puoi evitare le condizioni di gara se ritardi nell'assegnazione di posti specifici.

  1. Raccogliere le preferenze di posti a sedere dal cliente (numero di posti, prezzo, area del teatro, posti adiacenti obbligatori, ecc ...)
  2. Salva le preferenze di posti richieste in una coda
  3. Le richieste di posti a sedere uno a uno vengono ritirate dalla coda, i posti assegnati in base alle preferenze e la prenotazione completata se vengono trovati posti.
  4. Se la prenotazione è stata completata, avvisare i clienti e i biglietti postali; in caso contrario, informare il cliente che nessun biglietto corrisponde alle preferenze.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.