Comment un système de réservation de places de cinéma empêche-t-il plusieurs utilisateurs de réserver les mêmes places?

34

Dans la salle de cinéma où je vais, ils ont des kiosques à billets qui vous permettent de sélectionner les sièges que vous voulez; ils ont également un site Web qui fait la même chose (le site Web a également un compte à rebours de 30 secondes dans lequel vous devez choisir un siège).

Bien que je comprenne des choses telles que les transactions de base de données et d'autres techniques permettant de gérer plusieurs utilisateurs simultanés, je ne comprends tout simplement pas comment plusieurs personnes peuvent être autorisées à sélectionner un siège en même temps; Est-ce aussi simple que le premier à appuyer sur ACHETER obtient les sièges et l'autre personne recevra un message d'erreur, ou est-ce que je manque quelque chose?

Mbwasi
la source
10
"Est-ce aussi simple que le premier à appuyer sur ACHETER obtient les sièges et l'autre personne recevra un message d'erreur". Cette.
Yannis
2
Ouais, probablement, un beau jour avec une douzaine de machines, ça pourrait être pénible.
Mbwasi
2
Peut-être, mais gardez à l'esprit que les utilisateurs passeront la majorité de leur temps sur d'autres écrans (entrer les détails du paiement, attendre que les billets soient imprimés, etc.), afin qu'ils ne choisissent pas tous les sièges en même temps, et non tout le monde a les mêmes préférences en matière de sièges, alors même ceux qui choisissent en même temps choisiront probablement des sièges différents. Je ne m'attendrais pas à ce qu'il y ait autant de collisions.
Dave Sherohman
2
@ JimG. Pour chaque solution possible, si les deux clients appuient sur acheter au même moment précis (à la milliseconde près), l'un d'eux sera servi et l'autre recevra une sorte de message d'erreur. Il existe de beaux moyens de minimiser les risques que cela se produise (technique et conceptuel, comme expliqué dans les réponses), mais dans la situation extraordinaire qui se produit, une demande sera satisfaite et l'autre échouera. Aussi simple que cela.
Yannis
3
@ JimG. Ce n'est pas un type de comportement. La simultanéité fonctionne à un point, si les deux demandes atteignent exactement le même microtime, l'une d'entre elles échouera. Vous pouvez bien sûr créer un beau message d'erreur autour de cela, comme dans le commentaire de Hand-E-Food, mais le fait demeure: c'est aussi simple que de servir une demande et de faire échouer l'autre. Je ne dis pas que vous ne devriez pas tout faire pour que les échecs soient aussi faciles à utiliser que possible ou que vous ne devriez pas vous en prémunir.
Yannis

Réponses:

27

Pour ce faire, la méthode classique consiste à utiliser une base de données transactionnelle (afin d'éviter tout conflit) et à vous attribuer provisoirement le siège qui expire après un certain temps (par exemple 10 minutes pour les kiosques) qui vous laisse suffisamment de temps pour Payer. Si la transaction (visible par le client) échoue ou expire, l'attribution de sièges peut être libérée dans le pool. (Toutes les modifications d'état sont traitées via la base de données transactionnelle, et une transaction visible par le client peut nécessiter de nombreuses transactions au niveau de la base de données.)

Les compagnies aériennes utiliseront un système similaire (bien que beaucoup plus complexe en raison de la nécessité de gérer plusieurs vols!) Pour réserver des sièges en ligne. J'imagine que le délai d'attente serait considérablement plus long; les billets d'avion sont généralement réservés plus loin que les billets de cinéma, et sont également plus chers.

Donal Fellows
la source
Remarquez que ma salle de cinéma locale n'attribue pas de sièges normalement. Au lieu de cela, ils ont trop approvisionné les sièges afin que les gens puissent venir avec un minimum de problèmes. C'est une technique différente, mais pas pertinente pour votre question!
Donal Fellows
Semblable à choisir des sièges pour des événements sportifs. Vous obtenez votre nombre N de places réservées pendant 3 minutes pendant que vous décidez si vous les voulez réellement et effectuez le paiement.
AndyMcKenna
Notez qu'il existe deux processus différents, par exemple l'achat de sièges aériens: vous achetez un billet sans qu'un siège ne soit attribué. Deuxièmement, lorsque vous recevez votre carte d'embarquement (ou si vous vous enregistrez en ligne), vous obtenez un siège. Le nombre de billets est en réalité survendu car ils savent qu’en moyenne un certain nombre ne se présente pas pour le vol. L'attribution des sièges semble toutefois fonctionner en vous attribuant de manière aléatoire un siège (premier arrivé, premier servi) lors de l'enregistrement, puis en vous permettant de changer de siège en choisissant un siège disponible, puis d'effectuer le transfert en une seule transaction. .
Scott Whitlock
2
@DonalFellows pourriez-vous expliquer un peu plus la partie de l'allocation provisoire? Voulez-vous dire réserver des sièges à un utilisateur pendant un certain temps? J'essaie encore de maîtriser les difficultés rencontrées dans ce type de système.
Sandeepan Nath
1
@SandeepanNath Pas correctement dans un commentaire, mais le principe est trivial. Le siège est mis dans un état «provisoirement attribué» et le délai d'attente de cet état est noté en même temps. Si la réservation est terminée, le siège devient entièrement attribué. Si ce n'est pas le cas et que le délai est atteint, le siège est (éventuellement) replacé dans la piscine principale. (En outre, si l'utilisateur annule explicitement, le siège est directement transféré dans la piscine. Inutile d'attendre.)
Donal Fellows
4

Les 30 secondes que vous avez vues sont souvent plus proches de 15 minutes. Je ne crois pas qu'il y ait une transaction de base de données active pour cette durée.

Si je devais concevoir un tel système, voici comment je le ferais: avoir les objets métier Bookinget Reservation. Les réservations sont essentiellement des réservations confirmées (c'est-à-dire payées). Je voudrais les stocker dans la même table de base de données et distinguer par un attribut ou deux.

Lors de la recherche de places disponibles, vous devez interroger à la fois les réservations et les réservations.

Lorsque quelqu'un sélectionne un siège, vous créez une nouvelle réservation, montrant ainsi à d'autres clients le siège tel qu'il est pris. Une deuxième réservation pour le même siège sera refusée - la mise à jour ou l'insertion de la base de données échouera. Si le client confirme / paie pour la réservation, vous la passez en réservation. Dans un travail par lots périodique, vous supprimez toutes les réservations de plus de 15 minutes (ou l'heure que vous donnez à vos clients).

Hubert Grzeskowiak
la source
1

Il y a au moins deux processus opérationnels impliqués ici.

  • Processus un:

Afficher les places disponibles.

  • Processus deux:

Réservez une place choisie.

Étant donné que ces processus ne se succèdent pas de manière immodérée et que deux personnes peuvent choisir le même siège, le problème de la simultanéité se pose.

Si votre conception de base de données assigne la contrainte d'unicité correcte afin que la combinaison de:

-TheaterID

-SID

-EventID

sont uniques, la base de données empêchera les doublons.

Le scénario suivant est également possible mais sera pris en charge par la mise en œuvre suggérée ci-dessus:

En supposant qu'une vue de grille disponible pour un théâtre donné et un événement donné puisse être affichée:

  1. Utilisateur1 affiche les sièges disponibles (et obtient les sièges 1 et 2)
  2. User2 affiche les sièges disponibles (et obtient les sièges 1 et 2)
  3. Utilisateur1 parle un peu avec le client au téléphone
  4. User2 s'en va réserver le siège 2 pour son client
  5. L'utilisateur 1 essaie de réserver le siège 2 pour son client (car il apparaît comme disponible sur son écran)
  6. L'index unique empêche l'étape 5 de commuer les données.

Donc, tout ce que vous devez faire peut ne rien être de plus une conception de base de données correcte et un choix approprié de contraintes.

D'autres approches plus complexes sont possibles si vous le souhaitez, en utilisant des files d'attente de transactions. Dans ce cas, les demandes sont d'abord écrites dans une file d'attente, puis un processus est lancé toutes les n secondes, mais cela n'est guère nécessaire ou pratique dans votre cas.

La partie la plus intéressante est ce que la grille de liste pour l’utilisateur 1 devrait afficher.

Aucune chance
la source
1

Vous pouvez éviter la situation de concurrence critique si vous retardez l'attribution de sièges spécifiques.

  1. Recueillir les préférences de siège du client (nombre de sièges, prix, zone de théâtre, sièges adjacents obligatoires, etc.)
  2. Enregistrer les préférences de sièges demandées dans une file d'attente
  3. Les demandes individuelles de places assises sont extraites de la file d'attente, les places attribuées selon les préférences et la réservation effectuée si des places sont trouvées.
  4. Si la réservation est terminée, informez les clients et envoyez vos billets; sinon, informez le client qu'aucun billet ne correspond aux préférences.
Ed James
la source