Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Data MongoDB optimistic locking: save the version you read

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

A MongoDB @Version field turns a stale document save into a detectable conflict when writes are acknowledged.

A read-copy-write is a race

Two stock clerks load the same ParcelAllocation document at version 6. Both change its reservedUnits. Without a version condition, the later save can overwrite the earlier decision. With @Version, Spring Data adds the observed version to the write predicate and increments it on a successful update; a stale save raises OptimisticLockingFailureException. That is a conflict signal, not an automatic merge. JPA version checks solve a similar application problem through a different store.

Decide the retry contract

For a commutative increment, an atomic MongoDB update can avoid loading and replacing the full document. For a decision that depends on several fields, reload the latest document and re-evaluate the invariant after a conflict. Do not simply replay a stale object until it saves. Include tenantId in the query path so a valid document ID cannot select another tenant's allocation; identity validation happens before persistence.

Prove the conflict

Load two copies, save one, then attempt to save the other. Assert the second write fails and the first value remains. Use acknowledged writes; unacknowledged write concern can hide the failure. The entity sketch does not define a complete repository or HTTP conflict response, so test those boundaries separately.

Implementation sketch

Java
@Document("parcel_allocations")
class ParcelAllocation {
    @Id String id;
    String tenantId;
    int reservedUnits;
    @Version Long version;
}

Cost and verification

A versioned save adds a version predicate and conflict path. Under high contention, retries increase read and write traffic; a single atomic update may be cheaper for a simple counter.

Common Mistakes

  • Do not interpret an optimistic conflict as a request to overwrite with the stale document.
  • Do not use unacknowledged writes when the caller needs conflict detection.
  • Do not treat a document ID alone as tenant authorization.

Read next

Spring JPA optimistic locking: reject a stale stock update, Spring Data MongoDB tenant uniqueness: enforce it in an index, Spring Data MongoDB transaction: keep every write in one client session, Spring JWT tenant claims: reject missing or malformed ownership before conversion.

Related boundary

Spring Data Neo4j version conflicts: reject a stale graph update

spring
spring-boot
data-transactions
mongodb-versioned-document
Storage details