¿Cómo un sistema de reserva de asientos de cine evita que varios usuarios reserven los mismos asientos?

34

En el cine al que voy, tienen quioscos de boletos que te permiten seleccionar los asientos que deseas; también tienen un sitio web que hace lo mismo (el sitio web también tiene un temporizador de cuenta regresiva de unos 30 segundos en el que debe elegir un asiento).

Si bien entiendo cosas como las transacciones de la base de datos y otras técnicas para manejar múltiples usuarios simultáneos, no puedo entender cómo se puede permitir que varias personas seleccionen un asiento al mismo tiempo; ¿Es tan simple como que el primero que presione COMPRAR obtenga los asientos y la otra persona recibirá un mensaje de error, o me estoy perdiendo algo?

mbwasi
fuente
10
"¿Es tan simple como que el primero que presione COMPRAR obtenga los asientos y la otra persona recibirá un mensaje de error". Ese.
Yannis
2
Sí, probablemente, en un día ocupado con una docena de máquinas parece que sería un dolor.
mbwasi
2
Quizás, pero tenga en cuenta que los usuarios pasarán la mayor parte de su tiempo en otras pantallas (ingresando detalles de pago, esperando que se impriman los boletos, etc.), por lo que no todos elegirán asientos al mismo tiempo, y no todos tienen las mismas preferencias de asiento, por lo que incluso aquellos que eligen al mismo tiempo probablemente elegirán diferentes asientos. No esperaría que haya tantas colisiones.
Dave Sherohman el
2
@JimG. Para cada posible solución, si ambos clientes presionan comprar al mismo tiempo (al milisegundo), uno será atendido y el otro recibirá algún tipo de mensaje de error. Hay hermosas maneras de minimizar la posibilidad de que eso suceda (técnico y conceptual, como se explica en las respuestas), pero en la situación extraordinaria que sucede, se atenderá una solicitud y la otra fallará. Tan sencillo como eso.
Yannis
3
@JimG. No es un tipo de comportamiento. La concurrencia funciona hasta cierto punto, si ambas solicitudes llegan exactamente al mismo microtiempo, una fallará. Por supuesto, puede crear un buen mensaje de error al respecto, como en el comentario de Hand-E-Food, pero el hecho sigue siendo: es tan simple como atender una solicitud y fallar la otra. No digo que no debas hacer todo lo posible para asegurarte de que la falla sea tan fácil de usar como sea posible o que no debas salvaguardarte.
Yannis

Respuestas:

27

El método clásico para hacer esto es usar una base de datos transaccional (para que no haya conflictos) y hacer una asignación tentativa del asiento que caduque después de un período de tiempo (por ejemplo, 10 minutos para los quioscos) que le dé suficiente tiempo para paga. Si la transacción (visible para el cliente) fracasa o se agota el tiempo de espera, la asignación del asiento puede volver a liberarse en el grupo. (Todos los cambios de estado se procesan a través de la base de datos transaccional, y una transacción visible para el cliente puede requerir muchas transacciones a nivel de base de datos).

Las aerolíneas utilizarán un sistema similar (¡aunque mucho más complejo debido a la necesidad de manejar múltiples tramos de vuelo!) Para reservar asientos en línea. Me imagino que el tiempo de espera sería considerablemente más largo; los billetes de avión son generalmente reservado más adelante que las entradas de cine, y son más caros también.

Compañeros de Donal
fuente
Eso sí, mi cine local en realidad no asigna asientos normalmente. En cambio, sobreaprovisionaron los asientos para que las personas puedan aparecer con un mínimo de alboroto. ¡Es una técnica diferente, pero no relevante para su pregunta!
Donal Fellows el
Similar a la elección de asientos para eventos deportivos. Obtiene su número N de asientos reservados durante 3 minutos mientras decide si realmente los quiere y completa el pago.
AndyMcKenna
Tenga en cuenta que hay dos procesos diferentes con, por ejemplo, la compra de asientos de aerolíneas: primero, compra un boleto sin un asiento asignado. En segundo lugar, cuando obtiene su tarjeta de embarque (o si se registra en línea), obtiene un asiento. El número de boletos en realidad está sobrevendido porque saben que, en promedio, cierto número no aparece en el vuelo. Sin embargo, la asignación de asientos parece funcionar al asignarle al azar un asiento (primero en llegar) en el momento de registrarse, y luego le permite cambiar el asiento eligiendo uno disponible, luego haciendo la transferencia en una sola transacción .
Scott Whitlock, el
2
@DonalFellows, ¿podría explicar un poco más la parte de la asignación tentativa? ¿Te refieres a reservar algunos asientos para un usuario durante un período de tiempo? Todavía estoy tratando de acostumbrarme a los desafíos que se enfrentan en este tipo de sistema.
Sandeepan Nath
1
@SandeepanNath No correctamente en un comentario, pero el principio es trivial. El asiento se coloca en un estado "asignado provisionalmente", y el tiempo de espera de ese estado se anota al mismo tiempo. Si se completa la reserva, el asiento queda completamente asignado. Si no es así y se alcanza el tiempo de espera, el asiento (eventualmente) se mueve nuevamente hacia la piscina principal. (Además, si el usuario cancela explícitamente , el asiento se mueve directamente de regreso a la piscina. No es necesario esperar.)
Donal Fellows
4

Los 30 segundos que ha visto hoy en día suelen ser más de 15 minutos. No creo que haya una transacción de base de datos activa para esa duración.

Si tuviera que diseñar un sistema de este tipo, así es como lo haría: tener los objetos comerciales Bookingy Reservation. Las reservas son esencialmente confirmadas (es decir, pagadas). Los almacenaría en la misma tabla DB y distinguiría por un atributo o dos.

Al buscar asientos disponibles, debe consultar tanto las reservas como las reservas.

Cuando alguien selecciona un asiento, crea una nueva reserva, mostrando así a otros clientes el asiento como ocupado. Se rechazará una segunda reserva para el mismo asiento: la actualización o inserción de la base de datos fallará. Si el cliente confirma / paga la reserva, la pasa a una reserva. En un trabajo por lotes periódico, elimina todas las reservas de más de 15 minutos (o el tiempo que le dé a sus clientes).

Hubert Grzeskowiak
fuente
1

Aquí hay al menos 2 procesos de negocio involucrados.

  • Proceso uno:

Mostrar asientos disponibles.

  • Proceso dos:

Reserve un asiento seleccionado.

Dado que estos procesos no se siguen de manera inmoderada, y dado que 2 personas pueden seleccionar el mismo asiento, surge el problema de concurrencia.

Si el diseño de su base de datos asigna la restricción de unicidad correcta para que la combinación de:

-ID del teatro

-SeatID

-EventID

son únicos, entonces la base de datos evitará duplicados.

El siguiente escenario también es posible pero será atendido por la implementación sugerida anteriormente:

Suponiendo que se puede mostrar una vista de cuadrícula de disponible para un teatro y un evento determinados:

  1. Usuario1 muestra los asientos disponibles (y obtiene los asientos 1 y 2)
  2. Usuario2 muestra los asientos disponibles (y obtiene los asientos 1 y 2)
  3. Usuario1 habla un poco con el cliente por teléfono
  4. Usuario2 va y reserva el asiento 2 para su cliente
  5. El usuario1 intenta reservar el asiento 2 para su cliente (porque se muestra como disponible en su pantalla)
  6. El índice único evita que el paso 5 conmute los datos.

Entonces, todo lo que necesita hacer puede ser nada más que un diseño correcto de la base de datos y una elección adecuada de las restricciones.

Otros enfoques más complejos son posibles si lo desea, utilizando colas de transacciones. En este caso, las solicitudes se escriben primero en una cola y luego se activa un proceso cada n segundos, pero eso no es necesario ni práctico en su caso.

La parte realmente interesante es ¿qué debería mostrar la cuadrícula de la lista para el usuario 1?

Ninguna posibilidad
fuente
1

Puede evitar la condición de la carrera si retrasa la asignación de asientos específicos.

  1. Reúna las preferencias de asientos del cliente (número de asientos, precio, área de teatro, asientos adyacentes obligatorios, etc.)
  2. Guarde las preferencias de asientos solicitadas en una cola
  3. Las solicitudes de asientos uno por uno se retiran de la cola, los asientos se asignan según las preferencias y la reserva se completa si se encuentran asientos.
  4. Si se completa la reserva, notifique a los clientes y envíe los boletos por correo; de lo contrario, notifique al cliente que no hay tickets que coincidan con las preferencias.
Ed James
fuente