The hard part is not syncing; it is being wrong twice
At 08:17, a morning technician leaves depot coverage and updates an asset location on a handheld client. The asset moved from Bay 3 to North Yard after a repair handoff near the Plasma arc cutting station.
At 13:42, an afternoon technician opens the same stale asset record on another device and closes an inspection against the old location. Both edits look reasonable from the user’s seat. Both devices reconnect through depot Wi-Fi near shift end, and the batch upload finishes without an obvious error.
That is the failure mode that matters: the server reports a clean sync while preserving the wrong inspection state. The conflict rule picked a syntactically valid winner, but it did not understand the work.
Occasionally connected mobile applications fail this way when the sync layer treats enterprise records like replaceable cache rows. In older.NET mobile stacks, handheld clients, service layers, SQL Server Compact workloads, and custom synchronization code often shared responsibility for change tracking. The platform could detect that two versions existed; the domain service still had to decide what the conflict meant.
Note: A device that reconnects last may upload the earliest real-world observation, so arrival order cannot be treated as business order.
This article compares conflict models the way I evaluate them in mobile reliability work: not by elegance, but by what happens to the inspection, inventory count, work order, or safety observation after the radio comes back.
How to compare conflict models before picking one
Use the same checkpoints for every model
A conflict model should be judged against the record it protects. I use six checkpoints: conflict visibility, data loss risk, implementation complexity, audit trail depth, user interruption, and suitability for structured enterprise records.
Mobile workflows differ from generic distributed systems because disconnection is often part of the route design. A field worker may not know another worker changed the same record earlier in the day. The update may represent a physical-world action, not just a preference toggle or screen state.
Late-2000s and early-2010s.NET synchronization implementations commonly paired platform-level change tracking with domain rules in service code. The Microsoft Sync Framework documentation is useful historical context for that style of architecture, but it does not remove the need to define business conflict policy.
Conflict handling should move from business meaning to technical mechanism, not from database convenience to user cleanup.
Compact comparison table
Conflict model comparison for occasionally connected enterprise mobile systems
Strong when operation identity and replay history are retained
Low unless rejection paths involve users
Human review queue
Regulated, high-value, disputed, or safety-critical records
Backlog hides unresolved business decisions
Deep when the review packet is complete
High, but intentional
Last-write-wins and priority rules: fast, simple, and dangerous when meaning matters
Architecture overview
Overwrite models accept loss as policy. Timestamp-based last-write-wins compares the final accepted modification time. Server-wins, client-wins, and role-priority rules ignore at least some competing edits because a source, device, or role has been declared authoritative.
These models are not automatically careless. They work for cache refresh rows, non-critical preferences, disposable draft text, and values owned by a single upstream source. If the enterprise system is the only authority for a price list, a handheld client should not negotiate that value during sync.
Implementation detail
The dangerous case starts when the timestamp or source label stands in for business truth. A write made at 09:05 can arrive after a write made at 12:30 because the first device reconnects later. If the service orders conflicts by receipt instead of real-world capture, the wrong observation can win while the database stays perfectly consistent.
Server-wins has the same problem in a different jacket. It may be reasonable for reference data. It is a poor fit for inspection findings, inventory adjustments, compliance notes, safety checks, and service completion states where two edits may both describe real events.
Quick Tip: Before using an overwrite rule, name the value that can be safely discarded. If nobody wants to say that aloud, the record probably needs a different model.
Field-level merge: useful when records have independent meaning
Use case
Field-level merge compares each changed field instead of treating the whole row as one conflicting object. That matters when two workers touch different parts of the same structured record.
One technician changes asset location from Bay 3 to North Yard. Another enters a meter reading captured during the same route. If those fields are independent, rejecting one update because the row version changed wastes good field data.
Code-level requirements without the code sample
The service needs the original field value last downloaded to the device, the local edited value, the current server value, editor identity, and edit timestamp. With those values, the server can distinguish a clean field update from a true field collision.
After merging independent fields, run the same validation used for online saves. This is where many mobile sync designs get thin. A merged inspection can pass database validation yet fail domain logic if status, comment, and signature fields were resolved independently.
For example, changing status to failed inspection may require a reason code and supervisor signature. Merging the status without its supporting fields creates an invalid inspection even though every column has an acceptable type and length.
Something to consider: Field-level merge is reliable only when the domain model exposes its dependencies clearly enough for validation to reject impossible field combinations.
Operation-based resolution: preserve intent, not just values
Problem statement
Value-based conflict handling asks which final value should win. Mobile work often needs a better question: what did the user do?
An inventory adjustment conflict differs from an asset-description conflict because additive movement operations may preserve intent while text replacement usually cannot. If two workers scan received stock, replacing one final quantity with another may lose a legitimate movement. Replaying two receipt operations can preserve the work, provided the operations are valid and idempotent.
Technical approach
Operation examples include increment stock count by scanned receipt quantity, append safety observation, close task with completion evidence, and assign technician for next visit. The client stores a durable local operation queue. Each submitted operation carries an idempotency key, and the server applies a deterministic replay order.
Append-only notes and additive inventory movements often benefit from this model. The operation contains more business meaning than the current-value column.
Distributed-system ideas such as commutative operations and CRDT-like thinking can help frame the design. They should not be imported whole into enterprise mobile applications without domain review. Declaring equipment safe or releasing a customer-facing commitment needs stronger approval semantics than replay alone.
Performance implications
Operation queues increase storage and replay work on the service side. They also make testing more realistic, because reliability checks can exercise retries, duplicate submissions, rejected operations, and delayed uploads instead of only comparing row versions.
Human review queues: when automation should stop pretending
Use case
Some conflicts can be identified by software but not resolved by software. In those cases, the correct design is not a smarter overwrite rule. It is a review queue with ownership.
Regulated inspection forms, high-value asset state, disputed job completion, safety observations, and customer-facing commitments belong here. The review owner should be selected by domain responsibility, such as dispatch, supervision, compliance, or customer operations, not by whoever owns the database table.
What the UI must show
A useful review packet includes the original value, local edit, remote edit, local user identity, remote user identity, device identity, client timestamp, server receipt timestamp, and a required reason prompt. Labels should use business language such as inspection outcome and asset location, not raw column names or serialized payload fragments.
Unresolved conflicts need an owner queue and aging view. Otherwise the system hides a business decision behind a successful sync status, which is worse than showing an error.
In an Arc welding inspection route or an Air carbon cutting maintenance check, a supervisor does not want a payload diff. The supervisor wants to know who observed what, on which device, at what time, and why the chosen state should become the record of work.
A practical decision path for enterprise mobile architects
Step-by-step selection path
Classify data criticality. Separate preferences and cache rows from inspections, safety records, inventory movements, and customer commitments.
Identify authoritative sources. If one system truly owns a value, document that ownership and use priority rules only for that entity or field.
Test field independence. If fields can change separately without breaking validation, field-level merge may fit. If status, comment, signature, and reason code move together, treat them as a coupled set.
Decide whether user intent must be preserved. Use operation replay for additive or append-only work where the action matters more than the final displayed value.
Reserve manual review for high-risk exceptions. Give each review type an owner, a reason prompt, and an aging view before the first handheld rollout.
Combine models by entity type
A single global conflict policy is usually a convenience for the sync layer, not a service to the business. Preferences can use overwrite rules. Work-order headers may need field-level merge. Inventory movements may need operation replay. Safety exceptions may need human review.
Keep these policies close to domain services so handheld clients,.NET service layers, and custom sync components apply the same decision rules. Each entity type should have a named conflict policy, required audit fields, retry behavior, and escalation owner before implementation begins.
The right conflict model is the one that matches the business meaning of the change, not the one that is easiest to implement in the sync layer. Build the entity-by-entity conflict policy map next: start with the records that can change safety status, inventory balance, or customer commitment, and assign each a resolution model and an escalation owner before you touch the sync code.
Join the Conversation
Share your thoughts.
Your Comment