Conflict Resolution

Conflict resolution determines how concurrent or divergent writes are reconciled into an accepted state. In distributed Java backends, the strategy must define what happens when multiple replicas or clients update the same logical data without a single globally ordered write.

A conflict occurs when two or more valid writes cannot all be applied as though they happened sequentially. This commonly appears in replicated databases, distributed caches, offline-capable systems, and services that accept writes in more than one location. The system needs a deterministic or explicitly coordinated way to decide whether to keep one value, merge values, reject a write, or ask another component to resolve the disagreement.

A simple strategy is last-write-wins, where each value carries ordering metadata such as a timestamp or logical version and the system selects the value considered newest. This is easy to implement but can silently discard a legitimate update, and wall-clock timestamps can be problematic when clocks differ. Version numbers or logical clocks can provide stronger ordering information, but they still do not automatically determine how semantically different changes should be merged.

For application data, conflict resolution can instead be domain-specific. For example, independent fields may be merged when they were changed concurrently, while incompatible changes may require rejection or explicit reconciliation. Optimistic locking with a version column is another common approach: a write succeeds only if the stored version is still the one the client originally read, allowing the application to detect a concurrent update rather than silently overwriting it.

Idempotency is related but solves a different problem. Idempotency makes repeated processing of the same logical operation safe; conflict resolution determines what to do when distinct operations produce competing states. A robust design should also consider retries, ordering, duplicate delivery, partial failures, and whether losing an update is acceptable for the particular domain.

Key points

Interview questions

What is a write conflict in a distributed system?

A write conflict occurs when multiple valid operations modify the same logical data concurrently or when replicas have diverged. The system cannot simply apply the writes in an assumed global order. It therefore needs a rule such as rejecting stale writes, selecting one version, or merging the changes. The correct rule depends on the consistency and business requirements.

How does optimistic locking help with conflict resolution?

Optimistic locking associates a record with a version value that changes after a successful update. A client sends the version it originally read, and the update succeeds only if that version is still current. If another writer has already changed the record, the version check fails and the application can retry, merge, or report a conflict. This prevents a stale client from silently overwriting a newer update.

What are the trade-offs of last-write-wins?

Last-write-wins is straightforward because the system only needs an ordering mechanism and a deterministic selection rule. Its major drawback is that a valid update can disappear when another write is considered newer. Physical timestamps can also be affected by clock skew or inconsistent time sources. It is therefore more suitable when overwriting older state is acceptable than when every update carries independent business meaning.

How would you resolve conflicts when two updates modify different fields?

I would first determine whether the fields are truly independent from a business-invariant perspective. If they are independent, a field-level or domain-specific merge can preserve both changes. If changing either field affects a shared invariant, blindly merging them could create an invalid state, so the conflict should instead be rejected or resolved under an application-specific rule. The important point is that technical mergeability does not necessarily imply business-level correctness.

How are conflict resolution and idempotency different?

Idempotency concerns repeated execution of the same logical operation, such as a retry after an uncertain network response. Conflict resolution concerns competing operations that may both be valid but cannot all determine the final state. A request can therefore be idempotent while still conflicting with another request. Distributed systems often need both properties because retries and concurrent writes are separate failure modes.