Como um sistema de reserva de assentos no cinema impede que vários usuários reservem os mesmos assentos?


34

No cinema eu vou para eles têm quiosques de ingressos que permitem selecionar os assentos que você deseja; eles também têm um site que faz o mesmo (o site também possui um cronômetro de contagem regressiva de 30 segundos, no qual você deve escolher um lugar).

Embora eu compreenda coisas como transações de banco de dados e outras técnicas para lidar com vários usuários simultâneos, simplesmente não consigo entender como várias pessoas podem ter permissão para selecionar um assento ao mesmo tempo; é tão simples quanto o primeiro a pressionar COMPRAR obtém os assentos e a outra pessoa recebe uma mensagem de erro ou estou perdendo alguma coisa?


10
"é tão simples quanto o primeiro a pressionar COMPRAR obtém os assentos e a outra pessoa recebe uma mensagem de erro". Aquele.
yannis

2
Sim, provavelmente, em um dia agitado com uma dúzia de máquinas, parece que seria uma dor.
Mbwasi

2
Talvez, mas lembre-se de que os usuários passarão a maior parte do tempo em outras telas (inserindo detalhes de pagamento, aguardando a impressão dos ingressos etc.), para que nem todos estejam escolhendo assentos ao mesmo tempo, e não todo mundo tem as mesmas preferências de assento, portanto, mesmo aqueles que estão escolhendo ao mesmo tempo provavelmente escolherão lugares diferentes. Eu não esperaria que houvesse tantas colisões.
perfil completo de Dave Sherohman

2
@JimG. Para todas as soluções possíveis, se os dois clientes pressionarem comprar ao mesmo tempo (em milissegundos), um será atendido e o outro receberá algum tipo de mensagem de erro. Existem maneiras bonitas de minimizar a chance de isso acontecer (técnico e conceitual, conforme explicado nas respostas), mas na situação extraordinária que ocorre, um pedido será atendido e o outro falhará. Tão simples como isso.
yannis

3
@JimG. Não é um tipo de comportamento. A simultaneidade funciona até certo ponto, se ambas as solicitações atingirem exatamente o mesmo microtime, uma delas falhará. É claro que você pode criar uma boa mensagem de erro em torno disso, como no comentário do Hand-E-Food, mas o fato permanece: é tão simples quanto atender a uma solicitação e falhar na outra. Não estou dizendo que você não deve fazer tudo para garantir que a falha seja o mais amigável possível ou que você não deve salvaguardá-la.
yannis

Respostas:


27

O método clássico para fazer isso é usar um banco de dados transacional (para que não haja conflitos) e fazer uma alocação provisória do assento para você, que expira após algum tempo (por exemplo, 10 minutos para quiosques) que oferece tempo suficiente para você pagar. Se a transação (visível ao cliente) cair ou atingir o tempo limite, a alocação de assentos poderá ser liberada novamente no pool. (Todas as alterações de estado são processadas por meio do banco de dados transacional, e uma transação visível ao cliente pode exigir muitas transações no nível do banco de dados.)

As companhias aéreas usarão um sistema semelhante (embora muito mais complexo devido à necessidade de lidar com várias pernas de vôo!) Para reservar assentos online. Eu imaginaria que o tempo limite seria consideravelmente maior; as passagens aéreas geralmente são reservadas com mais antecedência do que as passagens de cinema e também são mais caras.


Veja bem, meu cinema local na verdade não aloca assentos normalmente. Em vez disso, eles provisionaram demais os assentos para que as pessoas pudessem aparecer com o mínimo de barulho. É uma técnica diferente, mas não relevante para a sua pergunta!
Donal Fellows

Semelhante à escolha de assentos para eventos esportivos. Você recebe seu número N de assentos por 3 minutos enquanto decide se os deseja e efetua o pagamento.
precisa saber é o seguinte

Observe que existem dois processos diferentes com, por exemplo, a compra de assentos de avião: primeiro, você compra um bilhete sem um assento alocado. Segundo, quando você recebe o seu cartão de embarque (ou se faz o check-in online), recebe um assento. O número de bilhetes é realmente vendido em excesso porque eles sabem que, em média, um determinado número não aparece no voo. A alocação de assentos, no entanto, parece funcionar, atribuindo-lhe um assento aleatoriamente (primeiro a chegar, primeiro a servir) quando você faz o check-in e, em seguida, permite alterar o assento, escolhendo um disponível e, em seguida, fazendo a transferência em uma única transação .
Scott Whitlock

2
@DonalFellows você poderia explicar um pouco mais a parte da alocação provisória? Você quer reservar alguns assentos para um usuário por um período de tempo? Ainda estou tentando entender os desafios enfrentados nesse tipo de sistema.
Sandeepan Nath

1
@SandeepanNath Não está bem em um comentário, mas o princípio é trivial. A sede é colocada em um estado "provisoriamente alocado" e o tempo limite desse estado é anotado ao mesmo tempo. Se a reserva for concluída, o assento será totalmente alocado. Caso contrário, e o tempo limite for atingido, o assento (eventualmente) será movido de volta para a piscina principal. (Além disso, se o usuário cancelar explicitamente , o assento será movido diretamente de volta para a piscina. Não há necessidade de esperar.)
Donal Fellows

4

Os 30 segundos que você viu são hoje em dia mais do que 15 minutos. Não acredito que haja uma transação de banco de dados ativa por esse período.

Se eu fosse projetar esse sistema, é assim que eu faria: Ter os objetos de negócios Booking e Reservation. As reservas são essencialmente confirmadas (ou seja, pagas). Eu os armazenaria na mesma tabela do banco de dados e distinguiria por um atributo ou dois.

Ao buscar assentos disponíveis, você consulta consultas e reservas.

Quando alguém seleciona um assento, você cria uma nova reserva, mostrando assim a outros clientes o assento como ocupado. Uma segunda reserva para o mesmo lugar será recusada - a atualização ou inserção do banco de dados falhará. Se o cliente confirmar / pagar pela reserva, você fará a transição para uma reserva. Em um trabalho em lotes periódico, você exclui todas as reservas com mais de 15 minutos (ou a qualquer momento que você der a seus clientes).



1

Existem pelo menos 2 processos de negócios envolvidos aqui.

  • Processo um:

Mostrar assentos disponíveis.

  • Processo dois:

Reserve um assento selecionado.

Como esses processos não se seguem imoderadamente, e como duas pessoas podem selecionar o mesmo lugar, surge o problema de concorrência.

Se o design do banco de dados atribuir a restrição de exclusividade correta para que a combinação de:

-TheaterID

-SeatID

-EventID

são exclusivos, o banco de dados evitará duplicatas.

O cenário a seguir também é possível, mas será resolvido pela implementação sugerida acima:

Supondo que uma visualização em grade disponível para um determinado teatro e um determinado evento possa ser exibida:

  1. O usuário1 exibe os assentos disponíveis (e obtém os assentos 1 e 2)
  2. O usuário2 exibe os assentos disponíveis (e obtém os assentos 1 e 2)
  3. Usuário1 fala um pouco com o cliente por telefone
  4. O usuário2 vai e reserva o assento 2 para seu cliente
  5. O usuário1 tenta reservar o assento 2 para o cliente (porque é exibido como disponível na tela)
  6. O índice exclusivo impede que a etapa 5 alterne os dados.

Portanto, tudo o que você precisa fazer pode ser nada mais do design do banco de dados correto e escolha adequada das restrições.

Outras abordagens mais complexas são possíveis, se você desejar, usando filas de transações. Nesse caso, as solicitações são gravadas primeiro em uma fila e, em seguida, acionam um processo a cada n segundos, mas isso dificilmente é necessário ou prático no seu caso.

A parte realmente interessante é o que a grade da lista para o usuário 1 deve mostrar?


1

Você pode evitar a condição de corrida se atrasar a alocação de assentos específicos.

  1. Coletar preferências de assentos do cliente (número de assentos, preço, área de teatro, assentos adjacentes obrigatórios, etc ...)
  2. Salve as preferências de assentos solicitadas em uma fila
  3. Os pedidos de assentos individuais são retirados da fila, os assentos são atribuídos de acordo com a preferência e a reserva é concluída se os assentos forem encontrados.
  4. Se a reserva for concluída, notifique os clientes e envie bilhetes por correio; caso contrário, notifique o cliente que nenhum ticket corresponde às preferências.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.