映画館の座席予約システムは、複数のユーザーが同じ座席を予約することをどのように防止しますか?


34

映画館には、チケットキオスクがあります。チケットキオスクを使用すると、必要な座席を選択できます。また、同じことを行うWebサイトもあります(Webサイトには、30秒程度のカウントダウンタイマーがあり、座席を選択する必要があります)。

データベーストランザクションや、複数の同時ユーザーを処理するためのその他のテクニックなどは理解していますが、複数の人が同時に座席を選択できる方法について頭を悩ますことはできません。BUYを押した最初の人が席を獲得し、他の人がエラーメッセージを受け取るのと同じくらい簡単ですか、それとも何かが足りませんか?


10
「購入ボタンを押した最初の人が席を獲得し、他の人がエラーメッセージを受け取るのと同じくらい簡単ですか」。それ。
ヤニス

2
たぶん、1ダースほどのマシンで忙しい日に、それは苦痛のように思えます。
mbwasi

2
おそらく、ただし、ユーザーは時間の大半を他の画面(支払いの詳細の入力、チケットの印刷待ちなど)に費やすため、すべての人が同時に席を選ぶわけではないことに注意してください誰もが同じ座席設定を持っているので、同時に選択している人でさえ、おそらく異なる座席を選択するでしょう。それほど多くの衝突があるとは思わないでしょう。
デイブシェロマン

2
@JimG。考えられるすべてのソリューションで、両方の顧客がまったく同じ時間(ミリ秒単位)で購入を押すと、一方が提供され、もう一方が何らかのエラーメッセージを受け取ります。その発生の可能性を最小限に抑える美しい方法があります(回答で説明されているように技術的および概念的)が、異常な状況では発生し、1つの要求が処理され、他の要求は失敗します。それと同じくらい簡単です。
ヤンニス

3
@JimG。それは一種の行動ではありません。並行性はある程度機能します。両方の要求がまったく同じマイクロタイムに到達すると、一方が失敗します。もちろん、Hand-E-Foodのコメントのように、それに関する素晴らしいエラーメッセージを作成することもできますが、事実は残ります。1つのリクエストを処理し、もう1つのリクエストを失敗させるのと同じくらい簡単です。失敗ができる限りユーザーフレンドリーであるようにするため、またはそれを回避するためにすべてを行うべきではない、と言っているのではありません。
ヤニス

回答:


27

これを行う古典的な方法は、トランザクションデータベースを使用して(衝突が発生しないようにする)、一定時間(たとえばキオスクの場合は10分)後に期限が切れる暫定的な座席割り当てを行うことです。支払う。(顧客から見える)トランザクションが失敗またはタイムアウトした場合、座席割り当てを解放してプールに戻すことができます。(すべての状態の変更はトランザクションデータベースを介して処理され、1つの顧客に見えるトランザクションは多くのデータベースレベルのトランザクションを必要とする場合があります。)

航空会社は、オンラインで座席を予約するために、同様のシステムを使用します(ただし、複数のフライト区間を処理する必要があるため、はるかに複雑です!)。タイムアウトはかなり長くなると思います。航空券は通常、映画のチケットよりも先に予約され、同様に高価です。


念のため、私の地元の映画館では、実際に座席を実際に割り当てていません。代わりに、彼らは座席を過剰にプロビジョニングして、人々が最小限の騒ぎでちょうど現れることができるようにしました。それは別のテクニックですが、あなたの質問に関連するものではありません!
ドナルドフェローズ

スポーツイベントの席を選ぶことに似ています。N席を3分間予約し、実際に希望するかどうかを決めて支払いを完了します。
AndyMcKenna

たとえば、航空会社の座席の購入には2つの異なるプロセスがあることに注意してください。まず、座席が割り当てられていないチケットを購入します。第二に、搭乗券を取得すると(またはオンラインでチェックインした場合)、座席を取得します。チケットの数が実際に売られすぎているのは、平均して、特定の数がフライトに現れないことを知っているからです。ただし、座席の割り当ては、チェックイン時に座席(先着順)をランダムに割り当て、利用可能な座席を選択して座席を変更し、1回のトランザクションで転送することで機能するようです。 。
スコットホイットロック

2
@DonalFellowsでは、暫定的な割り当て部分についてもう少し説明できますか?ある期間、ユーザーの座席を予約するつもりですか?私は、このタイプのシステムで直面する課題のこつを得ようとしています。
サンディーパンナス

1
@SandeepanNathコメントでは適切ではありませんが、原則は簡単です。シートは「暫定的に割り当てられた」状態になり、その状態のタイムアウトが同時に記録されます。予約が完了すると、座席は完全に割り当てられます。そうでなく、タイムアウトに達すると、座席は(最終的に)メインプールに戻されます。(また、ユーザーが明示的にキャンセルした場合、座席はプールに直接戻されます。待つ必要はありません。)
ドナルフェローズ

4

あなたが見た30秒は、今日では15分に近いことがよくあります。その期間中にアクティブなデータベーストランザクションがあるとは思わない。

このようなシステムを設計する場合、これは私が行う方法です。ビジネスオブジェクトBookingとを持っていますReservation。予約は基本的に確認済み(支払い済み)の予約です。それらを同じDBテーブルに格納し、1つまたは2つの属性で区別します。

利用可能な座席を取得する場合、予約と予約の両方を照会します。

誰かが座席を選択すると、新しい予約が作成され、他の顧客に座席が表示されます。同じ座席の2回目の予約は拒否されます-DBの更新または挿入は失敗します。顧客が予約の確認/支払いを行うと、予約に移行します。定期的なバッチジョブでは、15分(または顧客に提供する時間)よりも古い予約をすべて削除します。



1

ここには少なくとも2つのビジネスプロセスが関係しています。

  • プロセス1:

空席を表示します。

  • プロセス2:

選択した座席を予約します。

これらのプロセスは控えめに互いに追従しないため、2人が同じ座席を選択する可能性があるため、並行性の問題が発生します。

データベース設計で正しい一意性制約が割り当てられている場合、次の組み合わせになります。

-TheaterID

-SeatID

-EventID

一意である場合、データベースは重複を防ぎます。

次のシナリオも可能ですが、上記の提案された実装によって処理されます。

特定の劇場と特定のイベントで利用可能なグリッドビューを表示できると仮定すると:

  1. User1は利用可能な座席を表示します(そして座席1と2を取得します)
  2. User2は利用可能な座席を表示します(そして座席1と2を取得します)
  3. User1は電話で顧客と少し話します
  4. ユーザー2が顧客の席2を予約します
  5. User1は、顧客の座席2を予約しようとします(画面に空いていると表示されるため)
  6. 一意のインデックスにより、手順5でデータを交換できなくなります。

したがって、あなたがする必要があるのは、正しいデータベース設計と制約の適切な選択だけではないかもしれません。

必要に応じて、トランザクションキューを使用して、他のより複雑なアプローチが可能です。この場合、要求は最初にキューに書き込まれ、その後n秒ごとにプロセスを起動しますが、これはほとんど必要ないか、実用的ではありません。

本当に興味深いのは、ユーザー1のリストグリッドに何を表示するかです。


1

特定の座席の割り当てを遅らせると、競合状態を回避できます。

  1. 顧客から座席の好みを収集します(座席数、価格、劇場の面積、隣接する座席は必須など)
  2. 要求された座席設定をキューに保存します
  3. 順番に座席のリクエストがキューから取り出され、座席は好みに応じて割り当てられ、座席が見つかった場合は予約が完了します。
  4. 予約が完了したら、顧客に通知してチケットを郵送します。そうでない場合は、好みに一致するチケットがないことをお客様に通知します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.