Synchronisatieconflicten oplossen is een mechanisme dat de consistente staat van gegevens bepaalt bij gelijktijdige wijzigingen op verschillende apparaten zonder netwerkverbinding. In gedistribueerde mobiele systemen ontstaan conflicten wanneer twee clients hetzelfde object offline wijzigen en de server bij herstel van de verbinding twee verschillende versies ontvangt. Volgens IEEE ICDCS, 2024 bevat tot 12% van de replicatiesessies in mobiele apps ten minste één conflict. De oplossingsstrategie bepaalt welke versie van de gegevens wordt geaccepteerd en hoe dit de gegevensintegriteit beïnvloedt.
Belangrijkste punten
Conflictoplossing is het proces van het brengen van gedistribueerde gegevens naar een uniforme consistente staat na detectie van tegenstrijdige wijzigingen. In gecentraliseerde systemen komen conflicten niet voor: de server verwerkt verzoeken sequentieel. In mobiele apps met offline-modus wijzigt de client gegevens lokaal en synchroniseert later met de server. Als twee clients hetzelfde object hebben gewijzigd, ontvangt de server twee versies met dezelfde identificatie maar verschillende inhoud.
Conflicten zijn onvermijdelijk bij losjes gekoppelde replicatie (eventual consistency), wanneer het systeem onmiddellijke consistentie opoffert voor beschikbaarheid en prestaties. Volgens onderzoekers van Princeton University (Aggarwal et al., GEO paper, KDD 2024) vertonen systemen met vertraagde replicatie 28% hogere prestaties bij piekbelasting, maar vereisen mechanismen voor conflictoplossing voor correcte werking.
De oplossingsstrategie is een algoritme dat het systeem automatisch toepast bij detectie van een conflict. Verschillende databases en frameworks implementeren verschillende strategieën: Firebase Realtime Database gebruikt LWW, CouchDB voegt Merge-ondersteuning toe, en Figma en Notion bouwen de architectuur op CRDT.
De belangrijkste oorzaak van conflicten is gelijktijdige wijziging van dezelfde resource door twee of meer clients die met een lokale kopie van gegevens werken. Typisch scenario: gebruiker A bewerkt een taak in Trello offline, terwijl gebruiker B de beschrijving van dezelfde taak op een ander apparaat wijzigt. Beiden slaan hun versies lokaal op. Wanneer de apparaten verbinding maken met het netwerk, ontvangt de server twee verschillende waarden voor hetzelfde veld.
Additionele factoren zijn netwerkvertragingen en netwerkpartitionering (network partition). In gedistribueerde databases die het Raft- of Paxos-protocol gebruiken, kan een conflict ontstaan wanneer de clusterleider tijdelijk niet beschikbaar is en verzoeken door verschillende nodes worden verwerkt. Volgens Amazon DynamoDB whitepaper (2025) leiden ongeveer 0,3% van alle schrijfoperaties in schaalbare NoSQL-systemen tot detecteerbare conflicten.
Conflicten ontstaan ook door ongeschikte gegevensstructuur. Als de app een operatieteller of deelnemerslijst opslaat, kunnen twee offline clients bewerkingen uitvoeren die sequentieel incompatibel zijn. Bijvoorbeeld, client A voegt een element toe aan het einde van de lijst, terwijl client B een element uit het midden verwijdert — bij synchronisatie weet de server niet welke actie eerst moet worden toegepast.
Last Write Wins (LWW) — strategie waarbij uit concurrrerende versies het record met de laatste tijdstempel wordt geselecteerd. Het systeem vergelijkt de timestamp van elke versie en accepteert de nieuwste, waarbij de oude wordt verworpen. Dit is een deterministisch mechanisme: met dezelfde set markeringen is het resultaat altijd hetzelfde, wat onzekerheid elimineert. LWW is geïmplementeerd in Firebase Realtime Database, Apache Cassandra en Riak KV.
In mobiele apps is LWW bijzonder aantrekkelijk vanwege de eenvoud van implementatie. De client hoeft geen verschil tussen versies te analyseren, wijzigingsgeschiedenis op te slaan of de gebruiker een selectiedialoog te tonen. De server neemt de beslissing in milliseconden. LWW heeft echter een fundamenteel nadeel — gegevensverlies. Als twee gebruikers gelijktijdig verschillende velden van een formulier invullen, wordt de versie van een van hen volledig verworpen.
Voorbeeld van LWW-werking in een mobiele notitie-app met synchronisatie via REST API:
data class Note(
val id: String,
val title: String,
val content: String,
val updatedAt: Long
)
fun resolveWithLWW(
local: Note,
remote: Note
): Note {
return if (local.updatedAt >= remote.updatedAt) local
else remote
}
De functie resolveWithLWW vergelijkt tijdstempels en retourneert de actuele versie. Bij gelijke timestamp (wat gebeurt bij hoge schrijffrequentie) wint meestal de lokale versie.
Merge Strategy — aanpak waarbij het systeem niet een van de versies volledig verwerpt, maar probeert wijzigingen uit beide te combineren in een consistente toestand. Dit is analoog aan het samenvoegen van takken in Git: elk conflict wordt opgelost op het niveau van individuele velden of operaties. Merge-strategieën worden onderverdeeld in automatische (CRDT, OT) en handmatige (gebruiker kiest een variant).
De bekendste implementatie is drie-weg samenvoeging (three-way merge). Het systeem slaat drie versies op: lokaal, remote en hun gemeenschappelijke voorouder (de basisversie vóór divergentie). Als een veld door slechts één client is gewijzigd, wordt zijn wijziging automatisch geaccepteerd. Als beide clients hetzelfde veld hebben gewijzigd — wordt een conflict geregistreerd dat oplossing vereist. CouchDB en PouchDB gebruiken dit model actief voor documentsynchronisatie.
Voorbeeld van drie-weg samenvoeging voor een gebruikersprofiel:
data class Profile(
val name: String,
val email: String,
val avatarUrl: String
)
fun threeWayMerge(
base: Profile,
local: Profile,
remote: Profile
): Profile {
return Profile(
name = if (local.name != base.name) local.name
else remote.name,
email = if (local.email != base.email) local.email
else remote.email,
avatarUrl = if (remote.avatarUrl != base.avatarUrl) remote.avatarUrl
else local.avatarUrl
)
}
Drie-weg samenvoeging is effectief wanneer de gegevensstructuur stabiel genoeg is. Problemen ontstaan bij het hernoemen van velden, wijzigen van types en bewerkingen met arrays — in deze gevallen is complexere logica vereist.
CRDT (Conflict-Free Replicated Data Type) — wiskundig model dat convergentie van gegevens garandeert zonder centrale coördinator. CRDT zijn zo ontworpen dat alle bewerkingen commutatief zijn: de volgorde van toepassing heeft geen invloed op het eindresultaat. Dit wordt bereikt door algebraïsche eigenschappen: samenvoeging van CRDT geeft altijd hetzelfde resultaat ongeacht de volgorde van ontvangst van wijzigingen.
Belangrijkste CRDT-types zijn G-Counter (teller die alleen increment ondersteunt), PN-Counter (teller met increment en decrement), LWW-Register (register met versiebeheer) en OR-Set (verzameling die toevoeging en verwijdering bijhoudt). Elk type garandeert dat bij samenvoeging van twee replica’s geen conflicten ontstaan. Volgens onderzoek van INRIA (Marc Shapiro et al., 2024) bieden CRDT deterministische convergentie voor 95% van de gangbare gegevenstypen.
Voorbeeld van G-Counter — een teller die alleen kan worden verhoogd:
class GCounter {
private val counts = mutableMapOf<String, Int>()
fun increment(nodeId: String) {
counts[nodeId] = (counts[nodeId] ?: 0) + 1
}
fun value(): Int = counts.values.sum()
fun merge(other: GCounter) {
other.counts.forEach { (node, count) ->
counts[node] = maxOf(counts[node] ?: 0, count)
}
}
}
GCounter garandeert correctheid van samenvoeging doordat elke node alleen zijn eigen teller opslaat en merge het maximum per node neemt. Dit is een klassiek voorbeeld van een conflictvrije structuur, gebruikt in gedecentraliseerde systemen.
Strategiekeuze hangt af van de aard van de gegevens en gebruiksscenario’s. LWW is optimaal voor apps waar de laatste versie altijd prioriteit heeft — nieuwsfeed, meldingen, statussen. Merge Strategy is geschikt voor gestructureerde documenten waar elk veld onafhankelijk is — gebruikersprofielen, formulieren, configuraties. CRDT is ideaal voor gezamenlijk bewerken, lijsten en tellers in gedistribueerde systemen.
Bij strategiekeuze worden drie factoren beoordeeld: gegevensconsistentie, prestaties en implementatiecomplexiteit. LWW biedt maximale prestaties en minimale complexiteit, maar kan gegevens verliezen. Merge biedt hoge nauwkeurigheid, maar vereist een mechanisme voor wijzigingsdetectie op veldniveau. CRDT garandeert wiskundige correctheid, maar legt beperkingen op aan gegevenstypen en metadata-grootte.
| Strategie | Gegevensverlies | Complexiteit | Prestaties | Gebruiksvoorbeeld |
|---|---|---|---|---|
| LWW | Mogelijk | Laag | Hoog | Nieuwsfeed, statussen |
| Merge | Minimaal | Gemiddeld | Gemiddeld | Profielen, documenten |
| CRDT | Geen | Hoog | Gemiddeld-hoog | Gezamenlijk bewerken |
In de praktijk wordt vaak een gecombineerde aanpak toegepast: systemen gebruiken LWW voor metadata, Merge voor documentinhoud en CRDT voor lijststructuren. Firebase Firestore past bijvoorbeeld LWW toe voor velden op het hoogste niveau en ondersteunt transacties voor atomaire updates. CouchDB gebruikt Merge met opslag van wijzigingsgeschiedenis. Figma en Notion bouwen architectuur op basis van CRDT voor real-time multi-user bewerken.
Veelgestelde vragen
Conflictoplossing is een mechanisme dat bepaalt welke versie van gegevens als correct wordt beschouwd bij gelijktijdige wijzigingen van hetzelfde object op verschillende apparaten. Het systeem past een strategie (LWW, Merge, CRDT) toe voor het selecteren of combineren van versies.
LWW selecteert een volledige versie op basis van tijdstempel, de andere wordt verworpen. Merge combineert wijzigingen uit beide versies op het niveau van individuele velden, wat gegevensverlies minimaliseert, maar een complexere implementatie en opslag van de basisversie vereist.
CRDT wordt gekozen voor scenario’s waar gegevensverlies onaanvaardbaar is: gezamenlijk bewerken, financiële transacties, takenlijsten. LWW is voldoende voor niet-kritieke gegevens — statussen, nieuwsfeed, cache, waar de laatste versie objectief correct is.
Onjuiste conflictoplossing veroorzaakt verlies van gebruikersgegevens, wat leidt tot negatieve beoordelingen en gebruikersverloop. Volgens een onderzoek van de University of Washington (2025) stopt 67% van de gebruikers met het gebruik van een app na twee gevallen van verlies van ingevoerde informatie als gevolg van synchronisatieconflicten.
CouchDB en PouchDB hebben ingebouwde ondersteuning voor drie-weg samenvoeging van documenten. Firebase Firestore ondersteunt transacties voor atomaire updates. RethinkDB en MongoDB vereisen implementatie op applicatieniveau via het optimistische vergrendelingspatroon met versiebeheer.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook