Microservices Mastery
Lesson 3 of 30 10% of course

Database Per Service: Handling distributed data consistency

15 · 8 min · 5/23/2026

Sign in to track progress and bookmarks.

Database Per Service

The most controversial yet essential rule of microservices: Every service must own its own data. No other service is allowed to talk to your database. This ensures total decoupling, but it introduces the hardest problem in distributed systems: Distributed Data Consistency.

1. Why isolate the DB?

If Service A and Service B share a database, you cannot change the schema of Table X without breaking both. You have created a Shared-Database Monolith. By isolating the DB, Service A can switch to MongoDB while Service B uses PostgreSQL, and neither side cares.

2. How to "Join" data across services?

You cannot use a SQL JOIN across two microservices. There are two solutions:

  • API Aggregation (Facade): Call Service A, call Service B, and merge the results in your Gateway. (Slow).
  • Data Duplication (Projection): Service B listens for an event when Service A changes, and saves a "Copy" of the relevant data in its own database. (Fast, but eventually consistent).

4. Interview Mastery

Q: "If my services have separate databases, how do I handle a transaction that spans both (e.g., Create Order and Deduct Money)?"

Architect Answer: "You cannot use traditional ACID transactions (BeginTran/Commit) over a network. Instead, we use the **Saga Pattern**. A Saga is a sequence of local transactions. One service finishes its work and publishes a 'Success' event. The next service hears it and does its work. If a step fails, you must execute **Compensating Transactions** (Undo actions) to manually revert the previous steps. This is the price we pay for massive scalability."

Test your knowledge

Quizzes linked to this course—pass to earn certificates.

Browse all quizzes
Microservices Mastery

On this page

1. Why isolate the DB? 2. How to "Join" data across services? 4. Interview Mastery
1. Distributed Systems Fundamentals
Monolith vs Microservices: When to migrate? The 12-Factor App Methodology for Cloud-Native Apps Database Per Service: Handling distributed data consistency
2. Containerization & Orchestration
Docker Essentials: Building efficient .NET images Docker Compose: Orchestrating a multi-service environment Kubernetes Architecture: Pods, Services, and Deployments K8s ConfigMaps & Secrets: Managing environment variables Helm Charts: Packaging your microservices for K8s
3. Service Communication
Synchronous vs Asynchronous Communication: Pros and Cons REST APIs in a Microservices World: Best Practices Mastering gRPC: High-performance binary communication API Gateways: Implementing Ocelot for single-entry access BFF Pattern: Backend-for-Frontend (Mobile vs Web)
4. Event-Driven Architecture
Message Brokers: Introduction to RabbitMQ & Azure Service Bus Pub/Sub Pattern: Implementing MassTransit for .NET The Outbox Pattern: Ensuring 100% data consistency Dead Letter Queues: Handling message failure gracefully Distributed Transactions: The Saga Pattern (State Machines)
5. Resilience & Scalability
Distributed Caching with Redis: Optimizing global state Service Discovery: IdentityServer4 & Consul Load Balancing: Nginx vs Ingress Controllers The Sidecar Pattern: Offloading cross-cutting concerns
6. Observability & Security
Distributed Logging with Serilog & SEQ Distributed Tracing: OpenTelemetry & Jaeger Health Checks: Monitoring system vitals in real-time OAuth2 & OpenID Connect: Centralized Identity (AuthN/AuthZ) Rate Limiting & Throttling: Protecting your services
7. Advanced Cloud Topics
Infrastructure as Code (IaC): Introduction to Terraform CI/CD Pipelines for Microservices (GitHub Actions/Azure DevOps) C# Architect Interview: Microservices & System Design Focus