Uno de los errores más comunes al descomponer un monolito es separar la lógica de negocio en microservicios pero mantener una única base de datos centralizada. Esta práctica crea un acoplamiento oculto donde un cambio en el esquema de una tabla puede romper múltiples servicios simultáneamente, anulando la agilidad que buscábamos al distribuir el sistema. En este volumen, analizamos cómo la arquitectura de datos debe evolucionar para soportar el escalado independiente y la autonomía de los equipos.

El Problema: El Monolito de Datos y la Rigidez Transaccional
Cuando un negocio de E-Commerce crece, la necesidad de añadir funcionalidades de forma inmediata choca frontalmente con una base de datos relacional gigante. Al intentar que cada equipo sea dueño de su ciclo de vida, surgen fricciones críticas relacionadas con la persistencia:
- Dependencias de Esquema: Si el equipo de «Descuentos» modifica una columna que el equipo de «Pedidos» también consulta, ambos equipos quedan bloqueados en una espiral de coordinación eterna.
- Escalado Ineficiente: No todos los datos se comportan igual. El catálogo de productos requiere alta disponibilidad para lectura, mientras que el carrito de compras necesita una escritura ultra rápida de tipo clave-valor. Tener todo en un solo motor de base de datos obliga a escalar todo el sistema por el componente más exigente.
- Pérdida de Transacciones ACID: En el monolito, asegurar que un pedido se cree y el stock se descuente es sencillo. En microservicios, donde cada uno tiene su propia base de datos, no podemos usar una transacción tradicional para asegurar que ambos eventos ocurran.
La Solución: Database per Service y Persistencia Políglota
La solución fundamental es el patrón Database per Service. Cada microservicio debe ser el único dueño de su almacenamiento, lo que permite que el equipo de «Productos» elija Azure Cosmos DB por su flexibilidad documental, mientras que el equipo de «Pedidos» opta por Azure SQL por su robustez relacional.
Esta separación permite el escalado independiente: podemos aumentar las unidades de procesamiento de la base de datos de productos durante un Black Friday sin afectar el costo o el rendimiento de la base de datos de usuarios. Sin embargo, esto introduce el desafío de la consistencia. Para resolverlo, implementamos el patrón CQRS (Command Query Responsibility Segregation). Al separar las operaciones de escritura de las de lectura, podemos optimizar una base de datos para transacciones rápidas y replicar esos datos en una vista optimizada (como un índice de búsqueda en Azure Cognitive Search) para consultas complejas que involucren a varios servicios.
Notas para Azure y .NET
- Acepta la Consistencia Eventual: Entiende que en sistemas distribuidos, los datos pueden tardar milisegundos en sincronizarse entre servicios. Diseña tus aplicaciones .NET para manejar estados intermedios (ej. «Pedido en proceso» en lugar de «Completado» instantáneamente).
- Aislamiento Total de Conexiones: Asegúrate de que las cadenas de conexión a la base de datos de «Pedidos» solo existan en el microservicio de «Pedidos». Ningún otro servicio debe tener permiso para leer esas tablas directamente; deben solicitar la información a través de una API o un evento.
- Implementa Polyglot Persistence: No intentes forzar SQL Server para todo. Usa Azure Redis Cache para estados de sesión rápidos, Azure Blob Storage para archivos e imágenes, y reserva la base de datos relacional para lo que realmente requiere integridad referencial estricta.
Conclusión
La transición hacia microservicios traslada el desafío crítico del código a la conectividad, donde la exposición directa de múltiples endpoints genera latencia acumulada, debilidades en la seguridad y un acoplamiento excesivo del cliente que drena recursos en dispositivos móviles. Para mitigar este «caos de comunicación», la implementación del patrón API Gateway mediante Azure API Management permite consolidar peticiones, realizar agregación de datos y abstraer protocolos internos eficientes como gRPC. Al adoptar estrategias como el Backend for Frontends (BFF) y delegar políticas de seguridad, cuotas y throttling en la capa de entrada, el arquitecto logra proteger la lógica de negocio en .NET mientras optimiza la experiencia del usuario final con interfaces diseñadas a medida para cada plataforma.
