web-dev-qa-db-fra.com

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?

Dans la salle de cinéma, je vais à 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 pour gérer plusieurs utilisateurs simultanés, je n'arrive pas à comprendre 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?

34
mbwasi

La méthode classique pour ce faire est d'utiliser une base de données transactionnelle (donc il n'y a pas de conflits) et de vous faire allocation provisoire du siège qui expire après un certain temps (par exemple, 10 minutes pour les kiosques ) qui vous donne suffisamment de temps pour payer. Si la transaction (visible par le client) échoue ou expire, l'attribution des sièges peut être libérée dans le pool. (Tous les changements d'état sont traités 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 étapes de vol!) Pour réserver des sièges en ligne. J'imagine que le délai serait considérablement plus long; les billets d'avion sont généralement réservés plus en avance que les billets de cinéma et sont également plus chers.

28
Donal Fellows

Les 30 secondes que vous avez vues sont de nos jours souvent plus comme 15 minutes. Je ne crois pas qu'une transaction de base de données soit active pendant cette durée.

Si je devais concevoir un tel système, voici comment je le ferais: avoir les objets métier Booking et Reservation. Les réservations sont essentiellement confirmées (c'est-à-dire payées). Je les stockerais dans la même table DB et les distinguerais par un ou deux attributs.

Lors de la récupération des places disponibles, vous interrogez les réservations et les réservations.

Lorsque quelqu'un sélectionne un siège, vous créez une nouvelle réservation, montrant ainsi aux autres clients le siège tel qu'il a été 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 la réservation, vous passez à une réservation. Dans un travail par lots périodique, vous supprimez toutes les réservations de plus de 15 minutes (ou quelle que soit l'heure que vous accordez à vos clients).

4
Hubert Grzeskowiak

Vous pouvez éviter les conditions de course si vous retardez l'attribution de sièges spécifiques.

  1. Recueillir les préférences de sièges 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 de sièges un par un sont extraites de la file d'attente, les sièges sont attribués selon les préférences et la réservation est terminée si des sièges sont trouvés.
  4. Si la réservation est terminée, informez les clients et envoyez les billets par la poste; sinon, informez le client qu'aucun billet ne correspond aux préférences.
1
Ed James

Il y a au moins 2 processus métier impliqués ici.

  • Processus un:

Afficher les sièges disponibles.

  • Processus deux:

Réservez un siège sélectionné.

Étant donné que ces processus ne se succèdent pas de façon immodérée et que 2 personnes peuvent sélectionner le même siège, le problème de concurrence se pose.

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

-TheaterID

-SeatID

-EventID

sont uniques, la base de données évitera 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 de disponible pour un théâtre donné et un événement donné peut être affichée:

  1. L'utilisateur 1 affiche les sièges disponibles (et obtient les sièges 1 et 2)
  2. L'utilisateur 2 affiche les sièges disponibles (et obtient les sièges 1 et 2)
  3. L'utilisateur1 parle un peu avec le client au téléphone
  4. L'utilisateur 2 va réserver le siège 2 pour son client
  5. L'utilisateur 1 tente 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 n'est peut-être rien de plus correct dans la conception de la base de données et un choix approprié des 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 déclenche un processus toutes les n secondes, mais ce n'est guère nécessaire ou pratique dans votre cas.

La partie vraiment intéressante est ce que devrait montrer la grille de liste pour l'utilisateur 1?

1
NoChance

Il va avec la propriété ACID de la base de données - Isolation. La base de données utilise des verrous sur les données pour éviter la modification simultanée des données.

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

1
user841923