SpringDataPoly2026.md 12 KB


marp: true theme: uncover paginate: false size: 16:9 backgroundColor: #f4f5f7 color: #1f2933 style: | section {

font-size: 1.8em;

}

h1, h2, h3 {

color: #0f172a;

}

/* Texto secundario */ p, li {

color: #1f2933;

}

/* Cajas destacadas */ .box {

border: 3px solid #2563eb;
padding: 1em;
border-radius: 12px;
background-color: #e0e7ff;
color: #1e293b;

}

.box-compact{

font-size: 85% !important;
line-height: 1.5;

}

.box-supercompact{

font-size: 65% !important;
line-height: 1.2;

}

.left{

text-align: left;

}

.columns {

display: flex;
gap: 1em;
justify-content: center;
align-items: stretch;

}

.box.warning {

border-color: #ffeeba;
background-color: #fff3cd;

}

.box.danger {

border-color: #f5c6cb;
background-color: #f8d7da;

}

.box.success {

border-color: #c3e6cb;
background-color: #d4edda;

}

/* Alineación */ .left {

text-align: left;

}

/* Código */ pre, code {

background-color: #e5e7eb;
color: #111827;

} .w-30 { width: 30%; } .w-40 { width: 40%; } .w-50 { width: 50%; } .w-60 { width: 60%; } .w-70 { width: 70%; } .w-80 { width: 80%; } .center {

margin-left: auto;
margin-right: auto;

}


Spring Data:

Persistencia en Sistemas Políglotas y Reactivos



Daniel García Costa
2026

¿Qué es una arquitectura políglota?

  • Uso de múltiples tecnologías de almacenamiento en un mismo sistema
  • Cada tecnología se utiliza según sus fortalezas
  • No existe una única base de datos que resuelva todos los problemas
    Hay que usar la tecnología adecuada para cada situación

Relacionales (SQL)

| Tipo | Características principales | Casos de uso | Ejemplos | |-------------------------|--------------------------------------------------------------|--------------------------------------|--------------------------| | Relacional clásico | ACID, modelo tabular, integridad referencial | Aplicaciones empresariales, CRUD | PostgreSQL, MySQL | | OLTP | Optimizado para muchas transacciones pequeñas | Sistemas operacionales (apps, APIs) | PostgreSQL, Oracle | | OLAP / Data Warehouse| Optimizado para consultas analíticas complejas | BI, reporting, análisis de datos | Snowflake, Redshift | | HTAP (híbrido) | Mezcla OLTP + OLAP en tiempo real | Sistemas con analítica en vivo | TiDB, Azure SQL HTAP | | Distribuido | Escalado horizontal, replicación, particionado | Sistemas globales y escalables | CockroachDB, YugabyteDB |

No Relacionales (NoSQL)

| Tipo | Características principales | Casos de uso | Ejemplos | |--------------------|-----------------------------------------------------|---------------------------------------|---------------------| | Documentales | Datos JSON/BSON, esquema flexible | APIs, datos semiestructurados | MongoDB, CouchDB | | Clave-Valor | Acceso ultrarrápido por clave | Cache, sesiones, estado temporal | Redis, DynamoDB | | Grafos | Relaciones complejas entre nodos | Redes sociales, recomendaciones | Neo4j | | Columnar (Wide) | Columnas distribuidas, gran escalabilidad | Big Data, logs, eventos masivos | Cassandra, HBase | | Búsqueda | Indexación y búsqueda full‑text | Buscadores, analítica textual | Elasticsearch | | Series temporales| Optimizadas para datos con timestamp | IoT, métricas, monitoring | InfluxDB, Timescale | | Multi‑modelo | Soportan varios modelos en un mismo motor | Sistemas híbridos complejos | ArangoDB, Cosmos DB |

No hay una única solución óptima

Cada tipo resuelve un problema distinto

Por eso las arquitecturas modernas son políglotas


#### Complejidad - Uso de múltiples tecnologías == mayor complejidad global - Diferentes modelos de datos y APIs - Necesidad de orquestar varios sistemas

#### Puntos de fallo - Cada tecnología añade: - configuración propia - características específicas de despliegue - monitorización

--- ## Problemas más comunes ### Consistencia de datos - No hay transacciones distribuidas sencillas - Posibles inconsistencias: - estado actualizado en un sistema pero no persistido en otro - fallos en mitad del proceso
**Necesario diseñar tolerancia a fallos** --- ## Sincronización entre sistemas - ¿Cuándo mover los datos? - en tiempo real - mediante eventos - mediante schedulers
**El diseño del flujo de datos es crítico** --- ### Transformación de datos - Cada sistema tiene su propio modelo: - entidades (Java) - DTOs - documentos (Mongo) - Key/Value (Redis) - ... ### Dificultad de debugging - Errores distribuidos entre servicios - Fallos difíciles de rastrear: - llamadas remotas - errores de serialización - inconsistencias de datos --- ## Conclusión
**Mayor flexibilidad implica mayor responsabilidad**

Caso práctico: Plataforma de Subastas

Problema

Diseñar un sistema capaz de:

  • Gestionar subastas en tiempo real
  • Registrar pujas concurrentes
  • Mantener un histórico completo
  • Escalar correctamente ante múltiples usuarios

Enfoque arquitectónico

Uso de una arquitectura políglota

  • Diferentes tecnologías para distintos problemas
  • Separación entre:
    • estado en vivo
    • persistencia histórica

Objetivo

Construir un sistema:

  • escalable
  • modular
  • alineado con prácticas reales de arquitectura moderna

Tecnologías

  • BD relacional -> productos, categorías, usuarios... (integridad)
  • Redis -> estado activo de las subastas (velocidad)
  • MongoDB -> almacenamiento histórico (flexibilidad)
  • APIs REST -> integración entre servicios (desacoplamiento)
  • Spring Data REST -> exponer repositorios como API (agilidad)

MongoDB (Base de datos documental)

Características principales

  • Modelo basado en documentos (JSON / BSON)
  • Esquema flexible (no fijo)
  • Fácil evolución del modelo de datos
  • Soporte natural para estructuras anidadas

Casos de uso

  • Datos semiestructurados
  • Históricos y auditoría
  • Sistemas donde el modelo evoluciona
  • APIs modernas (JSON-centric)

### Ventajas - Flexibilidad de diseño - Alta productividad en desarrollo - Modelo cercano al dominio de negocio - Escalabilidad horizontal

### Desventajas - Menor control de integridad frente a SQL - Redundancia de datos - No ideal para transacciones complejas

Redis (Clave-Valor en memoria)

Características principales

  • Base de datos en memoria
  • Acceso extremadamente rápido (ms)
  • Modelo clave-valor
  • Soporte de TTL (expiración automática)
  • Estructuras avanzadas (listas, sets, etc.)

Casos de uso

  • Cache, Estado temporal, Sesiones, Sistemas en tiempo real

### Ventajas - Altísimo rendimiento - Simplicidad de uso - Ideal para datos efímeros - TTL nativo

### Desventajas - Persistencia limitada (según configuración) - No pensado como almacenamiento principal - Consumo de memoria

Spring Data REST

¿Qué es?

  • Componente de Spring que expone automáticamente repositorios como API REST
  • Genera endpoints CRUD sin necesidad de controladores
  • Basado en HATEOAS (Hypermedia)

¿Qué hace?

  • Expone entidades directamente como recursos REST
  • Genera endpoints como:
    • GET /api/items
    • GET /api/items/{id}
  • Incluye enlaces (_links) para navegación entre recursos

#### ¿Cuándo usarlo? - Prototipos rápidos - APIs CRUD simples - Sistemas con bajo control de lógica de negocio - Cuando se quiere reducir código boilerplate

#### ¿Cuándo NO usarlo? - Lógica de negocio compleja - APIs públicas que requieren mayor personalización - Necesidad de control fino sobre endpoints - Cuando el modelo interno no debe exponerse directamente

Resolviendo los desafíos

No intentar evitar la complejidad, hay que hacerla explícita y controlarla

  • Separación clara de responsabilidades
  • Flujo de datos bien definido
  • Uso de cada tecnología para lo que mejor sabe hacer
**Diseño orientado a evitar acoplamientos innecesarios**

Separación de responsabilidades

  • Relacional -> garantiza integridad
  • Redis -> estado en tiempo real
  • MongoDB -> persistencia histórica
  • API -> lógica de negocio

Beneficios

  • Cada componente hace una sola cosa
  • Menor complejidad interna por módulo
  • Sistema más mantenible
**Evitamos mezclar estado temporal con persistencia**

Control del ciclo de vida de las subastas

#### Problema - Redis elimina datos al expirar - No podemos recuperar el estado después

#### Solución Eliminamos dependencia de eventos internos - Definimos el tiempo de vida de nuestros eventos - Introducimos un **scheduler** para gestionar la persistencia

Flujo

  1. Subasta activa en Redis
  2. Scheduler detecta expiración
  3. Persistencia en Mongo
  4. Eliminación controlada


Control explícito del sistema


Transformación y enriquecimiento

#### Problema - Datos distribuidos en varios servicios - Representaciones incompletas

#### Solución - Feign obtiene entidades base - Resolución de relaciones - Construcción de DTO completo (enriquecidos)

Reactividad

NO es necesaria, pero si conveniente

  • Sistema con múltiples llamadas remotas
  • Necesidad de gestionar concurrencia de forma eficiente
  • Evitar bloqueos y mejorar rendimiento

#### Ventajas - Mejor uso de recursos - Alta capacidad de concurrencia - Código expresivo para flujos complejos

#### Inconvenientes - Mayor complejidad conceptual - Manejo cuidadoso de errores - Debugging más difícil

¿En qué casos merece la pena?

  • Obtener datos
  • Enriquecer información (usuario, categoría, etc.)
  • Persistir resultado final

Todo en un pipeline no bloqueante

La reactividad es una forma distinta de modelar el flujo del sistema

Resultado

  • Independencia de servicios externos
  • Gestión de llamadas no bloqueante
  • Datos listos para persistencia
    • Necesidad de integridad -> sistema relacional
    • Ciclo de vida -> Redis
    • Snapshot completo redundado -> Mongo



Todo esto está implementado en:


Vamos a ver algunas particularidades de la implementación