Existem pelo menos 2 processos de negócios envolvidos aqui.
Mostrar assentos disponíveis.
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:
- O usuário1 exibe os assentos disponíveis (e obtém os assentos 1 e 2)
- O usuário2 exibe os assentos disponíveis (e obtém os assentos 1 e 2)
- Usuário1 fala um pouco com o cliente por telefone
- O usuário2 vai e reserva o assento 2 para seu cliente
- O usuário1 tenta reservar o assento 2 para o cliente (porque é exibido como disponível na tela)
- 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?