CAP Theorem en la práctica con Spring Boot
Arquitectura distribuida, decisiones reales y una simulación CP vs AP
Los sistemas distribuidos no fallan “si ocurre algo extraño”.
Fallan porque la red es inherentemente no confiable.
Cuando diseñamos backend para producción real, el problema no es solo modelar entidades y exponer endpoints. El problema es decidir qué sacrificamos cuando la red falla.
Ese es el núcleo del Teorema CAP.
1. Fundamentos: qué es una partición
En un sistema distribuido existen múltiples nodos que se comunican por red.
Una partición de red ocurre cuando:
Los nodos siguen vivos.
Pero no pueden comunicarse entre sí.
No es caída total.
Es aislamiento parcial.
Ejemplo:
Nodo A X Nodo B
Ambos pueden aceptar escrituras.
Pero no pueden sincronizar estado.
Aquí nace el conflicto.
2. CAP Theorem (formal)
Formulado por Eric Brewer y formalizado por Gilbert y Lynch.
Establece:
En presencia de partición de red, un sistema distribuido solo puede garantizar Consistencia (C) o Disponibilidad (A), pero no ambas.
Donde:
Consistencia (C)
Después de una escritura exitosa, toda lectura posterior devuelve el valor más reciente.
Consistencia fuerte (linealizable).
Disponibilidad (A)
Cada request recibe respuesta válida (no error).
Partición (P)
El sistema continúa operando aunque existan fallos de comunicación entre nodos.
En sistemas reales, P es obligatoria.
La red puede fallar.
Por lo tanto, la decisión real es:
C o A bajo partición.
3. Trade-offs reales
Cuando ocurre una partición:
Opción 1 — CP (Consistencia + Partición)
Rechaza operaciones si no puede garantizar consistencia.
Sacrifica disponibilidad.
Ideal para:
Pagos
Inventario crítico
Sistemas financieros
Costo:
Errores temporales.
Mayor latencia.
Opción 2 — AP (Disponibilidad + Partición)
Siempre responde.
Puede devolver datos desactualizados.
Ideal para:
Redes sociales
Feeds
Métricas
Sistemas tolerantes a divergencia
Costo:
Inconsistencia temporal.
Necesidad de reconciliación.
4. Lo que CAP no dice
CAP no significa “elige dos y olvida el tercero”.
Significa:
Cuando la red falla, debes elegir entre consistencia o disponibilidad.
Sin partición, puedes tener ambas.
5. Simulación práctica en Spring Boot
Para entenderlo mejor, implementamos una API simple:
Dominio: Account
Campos:
id
balance
version
Creamos dos servicios:
CPAccountServiceAPAccountService
Y un simulador:
private volatile boolean partitioned;
Este flag representa la partición.
Endpoint de creación
POST /accounts
Crea una cuenta con balance inicial.
Endpoint CP
POST /accounts/{id}/cp/deposit
Lógica:
if (network.isPartitioned()) {
throw new RuntimeException("Partition detected - rejecting for consistency");
}
Comportamiento:
Bajo partición → error.
Sin partición → actualiza balance.
Consistencia fuerte garantizada.
Disponibilidad sacrificada.
Endpoint AP
POST /accounts/{id}/ap/deposit
Lógica:
Actualiza base principal.
Si no hay partición → sincroniza réplica.
Si hay partición → acepta escritura, réplica queda desactualizada.
Comportamiento:
Nunca bloquea.
Puede generar inconsistencia temporal.
Disponibilidad garantizada.
Consistencia eventual.
6. Respuestas HTTP estructuradas
Implementamos un wrapper:
public record ApiResponse<T>(
boolean success,
String message,
String strategy,
boolean partitioned,
T data,
Instant timestamp
) {}
Esto permite:
Saber si el sistema estaba particionado.
Saber qué estrategia se aplicó (CP o AP).
Trazabilidad temporal.
Respuestas uniformes.
7. Qué demuestra esta simulación
CAP no es teoría académica.
Es una decisión de negocio.
La elección se implementa en la capa de servicio.
El framework no decide. Tú decides.
La arquitectura refleja prioridades.
8. Escalabilidad y resiliencia
Un sistema resiliente:
Diseña para fallos.
Implementa timeouts.
Usa circuit breakers.
Implementa idempotencia.
Observabilidad desde el día uno.
CAP es solo el inicio.
La resiliencia es el objetivo final.
9. El ejemplo de la pizza (analogía)
Imagina dos sucursales de una pizzería:
Sucursal A
Sucursal B
Ambas comparten inventario digital.
Una tormenta corta la conexión entre ellas.
Queda solo una pizza disponible.
Escenario CP
Sucursal A intenta vender.
Pero como no puede confirmar con B,
bloquea la venta.
Resultado:
Nadie vende.
Inventario consistente.
Consistencia > disponibilidad.
Escenario AP
Ambas venden la pizza.
Resultado:
Se vendieron dos pizzas.
Inconsistencia.
Después habrá que resolver el conflicto.
Disponibilidad > consistencia.
10. Conclusión
CAP no es un debate técnico.
Es una decisión estratégica.
La pregunta correcta no es:
¿Qué arquitectura es mejor?
La pregunta correcta es:
¿Qué es más costoso para mi dominio: inconsistencia temporal o indisponibilidad temporal?
La ingeniería implementa la decisión.
El negocio la define.
Un backend avanzado no busca perfección.
Busca estabilidad bajo incertidumbre.