Java Omnibus
OOAD & Architecture / Microservices & Distributed Patterns / Database per Service
Database per Service Data Ownership Java Microservices
Microservices & Distributed Patterns

A service boundary is not real if another service can silently rewrite its truths through the same database.

Database per Service is one of the clearest tests of whether microservice boundaries are real. If multiple services still share ownership of the same tables, the architecture may have been split operationally but not conceptually. This pattern forces each service to own its data and publish information through APIs or events instead of backdoor queries.

Why This Topic Matters

Why it matters in real Java systems

Ordering should not inspect payment tables directly to decide whether an order is paid. It should know that through a contract from the payment capability. That protects autonomy, preserves local invariants, and makes ownership visible rather than implicit.

Core Explanation

The main design idea

Database per Service means each service owns its persistence model. Other services interact through contracts, not shared schema access. This improves encapsulation at the system level but complicates reporting, joins, and workflow coordination. Those concerns do not disappear; they move into integration patterns such as read models, events, and dedicated reporting pipelines.

The biggest gain is not just technical isolation. It is ownership clarity. Teams stop changing each other's data structures by accident and start negotiating explicit business contracts.

Concept Breakdown

Key ideas to keep in mind

Concept

Ownership

One service decides how its data is structured, validated, and evolved.

Concept

Integration by contract

Other services use APIs, events, or replicated read models instead of direct table joins.

Concept

Reporting shift

Cross-service queries move into separate projections or analytics pipelines.

Design consequences

Design consequences

Gain

True autonomy

Teams can evolve schema and persistence rules without hidden cross-service breakage.

Cost

No free joins

Queries that once relied on one transaction and one join now need projections, APIs, or asynchronous views.

Model impact

Explicit contracts

Events and query APIs become part of the design, not an afterthought.

Migration note

Split carefully

During migration, temporary duplication and synchronization work are normal and should be planned.

Java Example

Java example in the Order Management domain

Java example: published query instead of direct schema access
package org.javaomnibus.payments.api;

public interface PaymentStatusQuery {
    PaymentStatusView findByOrderId(OrderId orderId);
}

public record PaymentStatusView(
    String orderId,
    String authorizationStatus,
    Instant lastUpdatedAt
) {}
Code Walkthrough

Step by step

  1. The ordering side no longer reads payment tables directly.
  2. The payment capability exposes a contract shaped around business meaning.
  3. That contract may be served through HTTP, messaging, or a replicated read model depending on latency and scale needs.
  4. The important point is ownership: the schema stays local even when the information becomes shared.
Real-World Usage

Where this helps in practice

  • Separating payment, ordering, and shipment data ownership
  • Reducing accidental breakage from cross-team schema changes
  • Preparing a monolith for service extraction
Trade-Offs

Trade-offs and when to be careful

  • Database per Service strengthens autonomy, but it makes cross-service reporting and consistency more involved.
  • Some systems may remain better served by a modular monolith if the reporting and transactional coupling stay high.
Common Mistakes

Frequent mistakes to watch for

  • Allowing read-only cross-service table access that later becomes hidden write coupling
  • Forgetting to design read models for important cross-service queries
  • Treating database split as enough without fixing domain ownership
  • Breaking transactions apart without deciding how business recovery should work
Related Pages

Related concepts


What To Read Next