Wie verhindert ein Kino-Sitzplatzbuchungssystem, dass mehrere Benutzer denselben Sitzplatz reservieren?

34

Im Kino besuche ich sie mit Ticketschaltern, an denen Sie die gewünschten Plätze auswählen können. Sie haben auch eine Website, die das gleiche tut (die Website hat auch einen Countdown-Timer von etwa 30 Sekunden, in dem Sie einen Sitzplatz auswählen müssen).

Ich verstehe zwar Dinge wie Datenbanktransaktionen und andere Techniken für den Umgang mit mehreren gleichzeitigen Benutzern, kann mich aber nicht darauf konzentrieren, wie mehrere Personen gleichzeitig einen Sitzplatz auswählen dürfen. Ist es so einfach, dass die erste Person, die auf KAUF drückt, die Plätze bekommt und die andere Person eine Fehlermeldung erhält, oder fehlt mir etwas?

mbwasi
quelle
10
"Ist es so einfach, dass die erste Person, die auf KAUF drückt, die Plätze bekommt und die andere Person eine Fehlermeldung bekommt?" Das.
Yannis
2
Ja, wahrscheinlich scheint es an einem arbeitsintensiven Tag mit etwa einem Dutzend Maschinen ein Schmerz zu sein.
mbwasi
2
Vielleicht, aber denken Sie daran, dass Benutzer den größten Teil ihrer Zeit auf anderen Bildschirmen verbringen (Zahlungsdetails eingeben, auf den Ausdruck von Tickets warten usw.), damit sie nicht alle gleichzeitig Plätze auswählen und nicht Jeder hat die gleichen Sitzplatzpräferenzen, sodass selbst diejenigen, die zur gleichen Zeit auswählen, wahrscheinlich unterschiedliche Sitzplätze auswählen. Ich würde nicht erwarten, dass es so viele Kollisionen gibt.
Dave Sherohman
2
@JimG. Für jede mögliche Lösung wird, wenn beide Kunden genau zur gleichen Zeit (auf die Millisekunde genau) auf "Kaufen" klicken, einer bedient und der andere erhält eine Art Fehlermeldung. Es gibt schöne Möglichkeiten, das Risiko zu minimieren (technisch und konzeptionell, wie in den Antworten erläutert), aber in der außergewöhnlichen Situation wird eine Anfrage bearbeitet und die andere scheitert. So einfach ist das.
Yannis
3
@JimG. Es ist keine Art von Verhalten. Parallelität funktioniert bis zu einem gewissen Punkt. Wenn beide Anforderungen genau zur gleichen Zeit erreicht werden, schlägt eine fehl. Sie können natürlich eine nette Fehlermeldung darüber erstellen, wie im Kommentar von Hand-E-Food, aber die Tatsache bleibt: Es ist so einfach, eine Anfrage zu bedienen und die andere nicht zu beantworten. Ich sage nicht, dass Sie nicht alles tun sollten, um sicherzustellen, dass das Fehlschlagen so benutzerfreundlich wie möglich ist oder dass Sie sich nicht darum kümmern sollten.
Yannis

Antworten:

27

Die klassische Methode hierfür besteht darin, eine Transaktionsdatenbank zu verwenden (damit es nicht zu Konflikten kommt) und eine vorläufige Zuordnung des Sitzplatzes zu Ihnen vorzunehmen, die nach einer gewissen Zeitspanne (z. B. 10 Minuten für Kioske) abläuft, für die Sie genügend Zeit haben Zahlen. Wenn die (vom Kunden sichtbare) Transaktion ausfällt oder ein Timeout auftritt, kann die Sitzplatzzuweisung wieder in den Pool freigegeben werden. (Alle Statusänderungen werden über die Transaktionsdatenbank verarbeitet, und für eine vom Kunden sichtbare Transaktion sind möglicherweise viele Transaktionen auf Datenbankebene erforderlich.)

Die Fluggesellschaften werden ein ähnliches System verwenden (obwohl es aufgrund der Notwendigkeit, mehrere Flugstrecken zu bewältigen, sehr viel komplexer ist!), Um Sitzplätze online zu buchen. Ich würde mir vorstellen, dass das Timeout erheblich länger sein würde; Flugtickets werden in der Regel weiter im Voraus gebucht als Kinokarten und sind auch teurer.

Donal Fellows
quelle
Wohlgemerkt, mein lokales Kino weist normalerweise keine Plätze zu. Stattdessen haben sie die Sitze überbelegt, sodass die Leute mit minimalem Aufwand auftauchen können. Es ist eine andere Technik, aber keine, die für Ihre Frage relevant ist!
Donal Fellows
Ähnlich wie bei der Sitzplatzwahl für Sportveranstaltungen. Sie erhalten Ihre N Plätze für 3 Minuten reserviert, während Sie entscheiden, ob Sie diese tatsächlich möchten, und die Zahlung abschließen.
AndyMcKenna
Beachten Sie, dass es zwei verschiedene Verfahren gibt, wenn Sie beispielsweise Sitzplätze bei einer Fluggesellschaft kaufen: Erstens kaufen Sie ein Ticket ohne zugewiesenen Sitzplatz. Zweitens erhalten Sie einen Sitzplatz, wenn Sie Ihre Bordkarte erhalten (oder wenn Sie online einchecken). Die Anzahl der Tickets ist tatsächlich überverkauft, da sie wissen, dass im Durchschnitt eine bestimmte Anzahl für den Flug nicht angezeigt wird. Die Sitzplatzzuordnung scheint jedoch zu funktionieren, indem Sie beim Einchecken nach dem Zufallsprinzip einen Sitzplatz zuweisen (wer zuerst kommt mahlt zuerst) und dann den Sitzplatz ändern können, indem Sie einen verfügbaren auswählen und dann die Übertragung in einer einzelnen Transaktion durchführen .
Scott Whitlock
2
@DonalFellows könnten Sie den vorläufigen Zuweisungsteil etwas näher erläutern? Meinen Sie damit, einige Plätze für einen bestimmten Zeitraum für einen Benutzer zu reservieren? Ich versuche immer noch, die Herausforderungen in dieser Art von System zu meistern.
Sandeepan Nath
1
@ SandeepanNath Nicht richtig in einem Kommentar, aber das Prinzip ist trivial. Der Sitz wird in einen "vorläufig zugewiesenen" Zustand versetzt, und die Zeitüberschreitung dieses Zustands wird gleichzeitig notiert. Wenn die Buchung abgeschlossen ist, wird der Sitzplatz vollständig zugewiesen. Wenn dies nicht der Fall ist und das Timeout erreicht ist, wird der Sitz (eventuell) wieder in den Hauptpool verschoben. (Auch wenn der Benutzer explizit absagt, wird der Sitz direkt wieder in den Pool verschoben. Sie müssen nicht warten.)
Donal Fellows
4

Die 30 Sekunden, die Sie gesehen haben, sind heutzutage oft eher 15 Minuten. Ich glaube nicht, dass für diese Dauer eine Datenbanktransaktion aktiv ist.

Wenn ich ein solches System entwerfen würde, würde ich das folgendermaßen tun: Haben Sie die Geschäftsobjekte Bookingund Reservation. Buchungen sind im Wesentlichen bestätigte (dh bezahlte) Reservierungen. Ich würde sie in der gleichen DB-Tabelle speichern und durch ein Attribut oder zwei unterscheiden.

Wenn Sie freie Plätze abrufen, fragen Sie sowohl Buchungen als auch Reservierungen ab.

Wenn jemand einen Sitzplatz auswählt, erstellen Sie eine neue Reservierung und zeigen anderen Kunden den Sitzplatz als belegt an. Eine zweite Reservierung für denselben Sitz wird abgelehnt - die Aktualisierung oder Einfügung der Datenbank schlägt fehl. Wenn der Kunde die Reservierung bestätigt / bezahlt, wird sie in eine Buchung umgewandelt. In einem periodischen Batch-Job löschen Sie alle Reservierungen, die älter als 15 Minuten sind (oder wann immer Sie Ihren Kunden Zeit geben).

Hubert Grzeskowiak
quelle
1

Hier sind mindestens 2 Geschäftsprozesse beteiligt.

  • Prozess eins:

Freie Plätze anzeigen.

  • Prozess zwei:

Buchen Sie einen ausgewählten Sitzplatz.

Da diese Prozesse nicht maßlos aufeinander folgen und 2 Personen denselben Sitzplatz auswählen können, tritt das Problem der Parallelität auf.

Wenn Ihr Datenbankentwurf die korrekte Eindeutigkeitsbedingung zuweist, so dass die Kombination von:

-TheaterID

-SitzID

-EventID

sind eindeutig, dann verhindert die Datenbank Duplikate.

Das folgende Szenario ist ebenfalls möglich, wird jedoch von der oben vorgeschlagenen Implementierung berücksichtigt:

Angenommen, es kann eine Rasteransicht der für ein bestimmtes Theater und ein bestimmtes Ereignis verfügbaren Elemente angezeigt werden:

  1. Benutzer1 zeigt die verfügbaren Plätze an (und erhält die Plätze 1 und 2)
  2. Benutzer2 zeigt die verfügbaren Plätze an (und erhält die Plätze 1 und 2)
  3. Benutzer1 spricht ein wenig mit dem Kunden am Telefon
  4. User2 geht und bucht Platz 2 für seinen Kunden
  5. Benutzer1 versucht, Platz 2 für seinen Kunden zu buchen (da dies auf seinem Bildschirm als verfügbar angezeigt wird)
  6. Der eindeutige Index verhindert, dass Schritt 5 die Daten austauscht.

Alles, was Sie tun müssen, ist möglicherweise nichts mehr korrektes Datenbankdesign und die richtige Auswahl von Einschränkungen.

Andere komplexere Ansätze sind möglich, wenn Sie Transaktionswarteschlangen verwenden möchten. In diesem Fall werden Anforderungen zuerst in eine Warteschlange geschrieben und dann alle n Sekunden ein Prozess ausgelöst. Dies ist in Ihrem Fall jedoch kaum erforderlich oder praktisch.

Der wirklich interessante Teil ist, was das Listenraster für Benutzer 1 anzeigen soll.

Keine Chance
quelle
1

Sie können die Rennbedingung umgehen, wenn Sie die Zuteilung bestimmter Plätze verzögern.

  1. Sammeln Sie Sitzplatzpräferenzen beim Kunden (Anzahl der Sitzplätze, Preis, Theaterfläche, erforderliche Sitzplätze, usw.).
  2. Speichern Sie die gewünschten Sitzplatzeinstellungen in einer Warteschlange
  3. Einzelplatzanfragen werden aus der Warteschlange gezogen, Plätze werden nach Belieben vergeben und die Buchung ist abgeschlossen, wenn Plätze gefunden wurden.
  4. Wenn die Buchung abgeschlossen ist, benachrichtigen Sie die Kunden und senden Sie die Tickets. Andernfalls benachrichtigen Sie den Kunden, dass keine Tickets mit den Einstellungen übereinstimmen.
Ed James
quelle