Saltar al contenido
Yubarta Studio
← Blog

20 de julio de 2026 · 3 min de lectura

Por qué un advisory lock evita el doble-booking (y un check-then-act normal no)

El bug que parece imposible hasta que dos personas reservan a la vez

Un sistema de reservas típico revisa disponibilidad y después crea la reserva, en dos pasos separados: ¿está libre esta fecha? — sí — entonces la creo. El problema aparece cuando dos huéspedes hacen esa misma pregunta casi al mismo tiempo: ambos reciben “sí, está libre” antes de que ninguno haya reservado todavía, y los dos terminan creando una reserva para la misma habitación y las mismas fechas. No es un caso raro ni un error de programación descuidado — es una condición de carrera (race condition) clásica, y aparece justo cuando el negocio empieza a tener tráfico real, no en las pruebas de un solo usuario.

Por qué la solución obvia (revisar dos veces) no alcanza

La primera reacción suele ser “hay que revisar de nuevo justo antes de guardar” — pero eso solo reduce la ventana de tiempo del bug, no la elimina. Dos transacciones de base de datos pueden ejecutar exactamente esa segunda revisión al mismo tiempo, ver ambas que sigue libre, y seguir adelante las dos. El problema no es que falte una revisión, es que dos operaciones que dependen la una de la otra pueden ejecutarse en paralelo sin que ninguna sepa de la otra.

La solución real: serializar solo lo que necesita serializarse

La forma correcta de resolverlo es un advisory lock de PostgreSQL (pg_advisory_xact_lock): un bloqueo que la propia base de datos gestiona, atado a una llave específica (en este caso, el ID de la habitación) y que dura exactamente lo que dura la transacción. Mientras una reserva para esa habitación está siendo procesada, cualquier otra operación que pida el mismo bloqueo espera su turno — pero reservas para habitaciones distintas no se bloquean entre sí, porque cada una usa su propia llave. No hay que bloquear toda la tabla ni todo el sistema, solo la habitación específica que está en juego.

El mismo patrón, dos lugares distintos

En Nuquí Tours este patrón no vive en un solo lugar: aplica tanto cuando un huésped reserva directo desde el catálogo (createReservation) como cuando un administrador aprueba una cotización que ya estaba pendiente (respondToQuote) — son dos caminos distintos que terminan compitiendo por la misma disponibilidad, así que ambos usan la misma llave (hashtext del roomId) para el bloqueo. Si solo uno de los dos caminos estuviera protegido, el bug seguiría existiendo por la puerta de atrás.

Por qué esto importa incluso si tu negocio es chico

Este tipo de bug no se nota en desarrollo, con un solo usuario probando. Se nota el día que el negocio empieza a recibir tráfico real y, sin aviso, aparecen dos reservas para la misma cama la misma noche — un problema que después toca resolver a mano, disculpándose con un huésped. La ingeniería que evita esto no es visible para quien usa el sitio, pero es exactamente el tipo de trabajo que separa una plataforma real de un formulario con lógica encima.

¿Tu negocio necesita algo parecido a lo que hablamos acá?

Hablemos por WhatsApp