Una página de eventos puede tolerar una descripción antigua. Vender el mismo asiento a dos personas no es una demora aceptable. La palabra «consistencia» necesita asociarse a operaciones, datos y reglas concretas, no a una etiqueta global de toda la arquitectura.
El punto de partida es formular una invariante y señalar qué componente tiene autoridad para protegerla. Las copias de lectura, cachés y vistas derivadas pueden ayudar a servir información, pero no adquieren automáticamente el derecho de decidir una venta por estar disponibles.
Propiedades que responden preguntas distintas
| Propiedad | Pregunta útil |
|---|---|
| Atomicidad | ¿Qué cambios se confirman o abortan juntos? |
| Aislamiento | ¿Qué efectos de otras operaciones concurrentes puede observar una transacción? |
| Durabilidad | ¿Qué fallos admite la confirmación sin perder el cambio? |
| Visibilidad y frescura | ¿Qué versión puede observar una lectura y cuándo? |
| Autoridad | ¿Quién puede decidir el estado válido de este dato? |
Una transacción local puede ser atómica sin hacer toda lectura externa instantáneamente fresca. Una réplica durable puede estar retrasada. Una caché que responde rápido puede contener una versión anterior. Mantener separadas esas preguntas permite comparar mecanismos sin atribuirles garantías que no ofrecen.
Aislamiento y restricciones locales
En una base relacional, restricciones, condiciones de actualización y transacciones protegen reglas declaradas. Si dos compradores consultan primero «disponible» y después escriben «vendido», el precheck de la aplicación no evita la carrera. La decisión autoritativa debe coordinar esa transición y comprobar cuántas filas afectó o qué conflicto ocurrió.
PostgreSQL ofrece niveles de aislamiento con contratos diferentes. Read Committed puede observar snapshots distintos entre sentencias; Repeatable Read mantiene una vista más estable, pero no equivale a serializar todas las reglas posibles. Serializable puede abortar una transacción cuando no puede sostener un resultado serializable; la aplicación necesita reintentar la transacción completa de forma segura.
La identidad de operación y las restricciones de negocio siguen importando. Un nivel más fuerte no convierte un cobro externo en parte del commit. Tampoco reemplaza permisos o validación de entradas. La elección se comprueba con la invariante específica, bajo concurrencia y abortos.
Autoridad y proyecciones de inventario
En el sistema de boletaje, Postgres conserva reservas firmes y ventas; el mapa y la búsqueda muestran proyecciones. Si el mapa dice libre pero la transacción rechaza la reserva, prevalece la autoridad del inventario. La interfaz debe comunicar ese resultado y actualizar su vista.
La caché Redis puede ayudar a coordinar selecciones provisionales o descargar lecturas. Su TTL no decide por sí solo que un asiento está vendible. El hold_id, propietario y expiración se validan en el estado autoritativo al confirmar. Una copia ausente o vencida no invalida una reserva firme todavía vigente en la base.
--- config: look: handDrawn --- flowchart TD read["Consulta de eventos"] --> projection["Proyección o caché<br/>Frescura declarada"] write["Reserva de asiento"] --> authority[("Inventario autoritativo<br/>Restricción + transición atómica")] authority -->|"Commit"| event["Evento durable"] event --> projection authority --> result["Aceptación o conflicto"] projection --> view["Vista para el usuario"]
El evento puede llegar tarde. La respuesta de reserva procede de la transición autoritativa, no de asumir que todas las copias ya tienen la misma versión.
Lecturas entre réplicas y regiones
Una lectura puede necesitar read-your-writes, orden monotónico, una cota de obsolescencia o una decisión linealizable. Son contratos distintos. Después de escribir, enviar al cliente a una réplica retrasada puede mostrarle su orden como inexistente aunque la confirmación fuera válida.
Leer del primario o conservar una referencia de progreso puede ayudar, según el motor y la topología. Promover una réplica, cambiar rutas y perder respuestas introducen nuevas condiciones que deben verificarse. No basta llamar «fuerte» a una base sin explicar qué lecturas y escrituras reciben esa garantía.
Durante una partición de red, CAP ayuda a discutir si una operación puede continuar conservando su contrato de lectura y escritura. No es una selección genérica de «dos de tres» que determine todas las decisiones del producto. La búsqueda puede degradarse mientras una venta que exige autoridad rechaza o espera de forma acotada.
Fronteras distribuidas y estados intermedios
2PC coordina una decisión atómica de commit entre participantes preparados; el aislamiento de las lecturas necesita garantías adicionales del sistema. Puede retener recursos mientras se resuelve una decisión. No es equivalente a hacer cualquier operación distribuida instantánea.
Una Saga confirma pasos locales y representa estados intermedios. Compensar es un nuevo efecto de negocio, puede fallar y no borra automáticamente lo ocurrido. Encaja cuando el producto admite esa recuperación. Si una invariante requiere una decisión estricta común, deben colocarse sus datos bajo una autoridad adecuada o usarse las garantías distribuidas concretas del motor.
La outbox permite derivar vistas con recuperación, sin hacer atómicas sus lecturas con la autoridad. Sus lag y reglas de reconstrucción forman parte del contrato de esas vistas.
Declarar frescura y resolver conflictos
Una política de caché necesita decidir qué atraso es aceptable y qué ocurre si una lectura vieja repuebla una entrada después de invalidarla. Versiones y condiciones pueden evitar que una copia antigua reemplace una nueva. TTL por sí solo no garantiza una cota absoluta de edad si el origen o el repoblado ya estaban obsoletos.
Cuando se aceptan escrituras concurrentes, la regla de reconciliación pertenece al dominio. Last-write-wins puede perder un cambio válido, y los relojes de máquinas no forman por defecto un orden global fiable. Sumar contadores, asignar inventario y editar una descripción pueden necesitar estrategias diferentes.
Comprobar las reglas observables
Las pruebas introducen compradores simultáneos, lecturas desde réplicas retrasadas y una pérdida de conectividad entre regiones. También invalidan caché durante una lectura lenta, abortan transacciones serializables y dejan una Saga parcialmente completada. La comprobación observa la invariante, no sólo el código HTTP.
Se registra autoridad de cada decisión, versión leída, conflictos y estados de recuperación. La observabilidad debe permitir explicar una respuesta vieja sin confundirla con una pérdida de datos, y reconocer una violación real aunque todas las peticiones hayan devuelto éxito.
Referencias: aislamiento de transacciones y restricciones de integridad en PostgreSQL.