Offline-Sync-Konfliktlösung: Strategien für mobile Apps
AI generated
RN
native
React Native / Datenmanagement
Offline-Sync-Konfliktlösung
Strategien für mobile Apps, die auf mehreren Geräten gleichzeitig offline arbeiten

Sobald zwei Geräte denselben Datensatz offline bearbeiten und beide anschließend synchronisieren, entsteht zwangsläufig ein Konflikt, den die App auflösen muss. Dieser Artikel zeigt, wie solche Konflikte technisch entstehen, welche Auflösungsstrategien sich in der Praxis bewährt haben und wo automatische Lösungen an ihre Grenzen stoßen.

11 Min. Lesezeit Konfliktlösung Sync-Strategien

1. Wie Synchronisationskonflikte technisch entstehen

Ein Synchronisationskonflikt entsteht, sobald zwei Geräte offline denselben Datensatz verändern und beide Änderungen anschließend gegen denselben Server-Zustand ausgespielt werden. Der Server kennt zum Zeitpunkt der ersten eingehenden Änderung nur eine Version, sieht aber kurz darauf eine zweite Anfrage, die von genau derselben Ausgangsversion ausgeht, obwohl der Datensatz inzwischen bereits verändert wurde.

Bei mobilen Apps tritt dieses Szenario deutlich häufiger auf als bei reinen Web-Anwendungen, weil Flugmodus, U-Bahn-Fahrten und schwankende Netzabdeckung längere Offline-Fenster erzeugen. Zwei Außendienstmitarbeiter, die zeitgleich denselben Kundendatensatz auf ihrem Gerät bearbeiten, produzieren dabei fast zwangsläufig widersprüchliche Änderungen, die erst beim nächsten erfolgreichen Sync-Vorgang sichtbar werden.

2. Last-Write-Wins: einfache Regel mit stillen Datenverlusten

Last-Write-Wins ist die einfachste Konfliktlösung: Der Änderung mit dem höchsten Zeitstempel wird der Vorzug gegeben, die andere wird stillschweigend verworfen. Die Regel lässt sich mit wenigen Zeilen Code implementieren und funktioniert für unkritische Werte wie einen zuletzt geöffneten Ordner oder eine Sortiereinstellung meist völlig ausreichend.

Problematisch wird Last-Write-Wins, sobald Geräteuhren nicht exakt synchron laufen oder ein Gerät zeitweise ohne Netzverbindung war und seine Uhrzeit erst später korrigiert. In diesem Fall gewinnt nicht die tatsächlich zuletzt getroffene Entscheidung, sondern die Änderung mit der zufällig höheren Client-Uhrzeit, was bei geschäftskritischen Feldern zu unbemerktem Datenverlust führt.


// Naive Last-Write-Wins-Implementierung im Sync-Layer
type Record = { id: string; updatedAt: number; payload: Record<string, unknown> };

function resolveLastWriteWins(local: Record, remote: Record): Record {
  // Achtung: verlässt sich vollständig auf die Client-Uhrzeit,
  // Uhren-Drift zwischen Geräten wird hier nicht erkannt.
  return local.updatedAt >= remote.updatedAt ? local : remote;
}

3. Feldbasierte Merge-Strategien statt ganzer Datensätze

Statt einen kompletten Datensatz zu überschreiben, vergleicht ein feldbasiertes Merge jeden einzelnen Wert mit seinem eigenen Änderungszeitstempel. Ändert ein Gerät nur die Telefonnummer eines Kontakts und ein anderes Gerät zeitgleich nur die Notiz, bleiben beide Änderungen erhalten, weil sie sich schlicht nicht überschneiden.

Diese Strategie reduziert die Anzahl echter Konflikte erheblich, weil in vielen Formularen die meisten Felder unabhängig voneinander bearbeitet werden. Der Preis dafür ist zusätzlicher Speicheraufwand, da pro Feld ein eigener Zeitstempel und teilweise ein eigener Änderungszähler mitgeführt werden muss, statt nur eine einzige Spalte für den gesamten Datensatz zu pflegen.


// Feldbasiertes Merge: nur tatsächlich kollidierende Felder werden geprüft
type FieldMeta = { value: unknown; changedAt: number };
type Entity = Record<string, FieldMeta>;

function mergeFields(local: Entity, remote: Entity): Entity {
  const result: Entity = { ...local };
  for (const key of Object.keys(remote)) {
    const remoteField = remote[key];
    const localField = local[key];
    if (!localField || remoteField.changedAt > localField.changedAt) {
      result[key] = remoteField;
    }
  }
  return result;
}

4. Konflikterkennung mit Versionsvektoren und Änderungszählern

Reine Zeitstempel verraten nur, welche Änderung später erfolgt ist, nicht aber, ob zwei Änderungen tatsächlich gleichzeitig und unabhängig voneinander entstanden sind. Versionsvektoren lösen dieses Problem, indem jedes Gerät einen eigenen Zähler pro Datensatz führt und diesen bei jeder lokalen Änderung erhöht.

Vergleicht der Server zwei Versionsvektoren, erkennt er zuverlässig, ob eine Änderung linear auf der anderen aufbaut oder ob beide unabhängig voneinander, also nebenläufig, entstanden sind. Nur im zweiten Fall liegt ein echter Konflikt vor, der eine Auflösungsstrategie benötigt, während eine rein sequentielle Änderungskette automatisch und ohne Risiko übernommen werden kann.

5. Operational Transformation und CRDTs im mobilen Kontext

Operational Transformation stammt aus kollaborativen Texteditoren und transformiert eingehende Operationen so, dass sie unabhängig von der Reihenfolge zum gleichen Endergebnis führen. Für klassische mobile CRUD-Apps mit Formularen ist dieser Ansatz meist überdimensioniert, weil er eine zentrale Transformationslogik voraussetzt, die für jede Feldkombination korrekt definiert sein muss.

Conflict-free Replicated Data Types, kurz CRDTs, garantieren dagegen mathematisch, dass mehrere Replikate ohne zentrale Koordination zum selben Ergebnis konvergieren. Bibliotheken wie Automerge oder Yjs eignen sich gut für Zähler, Mengen oder kollaborativen Text, bringen aber deutlich größere Metadaten mit sich und erschweren die Fehlersuche in einfachen Geschäftsdatensätzen spürbar.

6. Benutzergesteuerte Konfliktauflösung: wenn Automatik nicht ausreicht

Manche Konflikte dürfen nicht automatisch entschieden werden, etwa wenn zwei Vertriebsmitarbeiter offline unterschiedliche Rabatte für denselben Auftrag hinterlegt haben. In solchen Fällen sollte die App den Konflikt sichtbar machen, beide Versionen nebeneinander anzeigen und dem Nutzer die aktive Entscheidung überlassen, statt eine der beiden Änderungen stillschweigend zu verwerfen.

Praktisch bewährt sich dafür eine dedizierte Konflikt-Warteschlange, die betroffene Datensätze so lange zurückhält, bis der Nutzer eine Entscheidung getroffen hat. Erst nach dieser Entscheidung wird der Datensatz endgültig synchronisiert, während alle anderen, konfliktfreien Änderungen weiterhin automatisch im Hintergrund verarbeitet werden.


function ConflictBanner({ local, remote, onResolve }: ConflictProps) {
  return (
    <View style={styles.banner}>
      <Text style={styles.title}>Widersprüchliche Änderung erkannt</Text>
      <Text>Lokal: {local.discount}% Rabatt</Text>
      <Text>Server: {remote.discount}% Rabatt</Text>
      <View style={styles.actions}>
        <Button title="Lokale Version behalten" onPress={() => onResolve(local)} />
        <Button title="Server-Version übernehmen" onPress={() => onResolve(remote)} />
      </View>
    </View>
  );
}

7. Praktische Sync-Engines: WatermelonDB, RxDB und Automerge im Vergleich

WatermelonDB folgt dem Muster pullChanges und pushChanges und liefert standardmäßig eine einfache Last-Write-Wins-Logik, erlaubt aber, einen eigenen Resolver zwischen dem Pull- und dem Push-Schritt einzuhängen. RxDB arbeitet mit einer Revisionskette pro Dokument und erkennt Konflikte, sobald die lokale Revision nicht mehr zur erwarteten Server-Revision passt.

Automerge geht einen grundsätzlich anderen Weg und führt Änderungen als CRDT automatisch zusammen, ganz ohne expliziten Konfliktschritt, was für strukturierte Dokumente wie Notizen oder Konfigurationen gut funktioniert. Für klassische relationale Geschäftsdaten mit Fremdschlüsseln bleibt in der Praxis meist eine Kombination aus feldbasiertem Merge und einer schmalen manuellen Eskalationsschicht die robustere Wahl.

8. Konfliktszenarien gezielt testen statt hoffen

Konfliktlösung lässt sich nicht durch manuelles Ausprobieren zuverlässig absichern, weil das Zusammenspiel aus Netzwerktiming und lokalem Zustand kaum reproduzierbar ist. Sinnvoller ist ein Integrationstest, der zwei simulierte Clients denselben Ausgangsdatensatz offline verändern lässt und anschließend beide Änderungen nacheinander gegen denselben Server-Endpunkt schickt.

Ergänzend lohnt sich gezieltes Chaos-Testing mit zufälligen Offline-Fenstern und verzögerten Antworten, etwa über eine gemockte NetInfo-Implementierung in React Native. Auf Serverseite gehört zusätzlich ein Idempotenz-Check dazu, der doppelt eingehende Änderungen erkennt und verhindert, dass eine wiederholte Sync-Anfrage nach einem Verbindungsabbruch versehentlich einen weiteren Konflikt erzeugt.

9. Grenzen automatischer Auflösung in der Praxis

Bei Lagerbeständen, Preisen oder Zahlungsstatus ist automatisches Merge riskant, weil ein falsch zusammengeführter Wert direkte finanzielle Folgen haben kann. Für solche Felder sollte die Automatisierung bewusst eskalieren, statt eine plausibel klingende, aber möglicherweise falsche Annahme zu treffen und den Konflikt intransparent im Hintergrund zu verstecken.

In der Praxis bewährt sich ein hybrider Ansatz: automatische Auflösung für risikoarme Felder wie Notizen oder Ansichtspräferenzen, eine manuelle Prüfungswarteschlange für geschäftskritische Felder sowie ein durchgängiges Änderungsprotokoll, das jede Konfliktentscheidung nachvollziehbar dokumentiert und im Streitfall als Nachweis dient. Diese Kombination aus Automatisierung und gezielter menschlicher Kontrolle lässt sich schrittweise einführen und muss nicht von Anfang an jedes Feld abdecken, sondern kann zunächst auf die offensichtlich riskantesten Datenpunkte beschränkt bleiben, bevor sie auf weitere Bereiche der App ausgeweitet wird.

Strategie Funktionsweise Geeignet für Risiko
Last-Write-Wins Höchster Zeitstempel gewinnt, unterlegene Änderung wird verworfen Unkritische Einzelwerte wie Ansichtspräferenzen Stille Datenverluste bei Uhren-Drift
Feldbasiertes Merge Jedes Feld erhält einen eigenen Zeitstempel, unabhängige Felder bleiben erhalten Formulare mit mehreren unabhängigen Feldern Erhöhter Speicher- und Prüfaufwand pro Feld
CRDT-basierte Typen Mathematisch garantierte Konvergenz ohne zentrale Instanz Kollaborative Texte, Zähler, Mengen Größere Metadaten, komplexere Fehlersuche
Versionsvektoren Erkennung echter Konflikte statt reiner Zeitreihenfolge Verteilte Systeme mit mehreren Schreibern Zusätzliche Serverlogik zur Auswertung
Benutzergesteuerte Auflösung Nutzer erhält Diff-Ansicht und entscheidet aktiv Geschäftskritische Felder wie Preise oder Mengen Unterbricht den Workflow, erfordert UI-Aufwand

Mironsoft

React-Native-App-Entwicklung und Magento-Anbindung

Eine mobile App zum Magento-Shop, die wirklich rund läuft?

Wir entwickeln React-Native-Apps, die sauber an die Magento REST- oder GraphQL-API angebunden sind, von der ersten Codezeile bis zur Veröffentlichung im App Store und bei Google Play.

App-Konzeption

Architektur und Feature-Umfang einer Magento-angebundenen App gemeinsam planen.

Magento-API-Integration

Produktkatalog, Warenkorb und Checkout sauber an die Shop-API anbinden.

Store-Veröffentlichung

App Store- und Google-Play-Freigabeprozess ohne Stolperfallen begleiten.

10. Zusammenfassung

Offline-Sync-Konfliktlösung: Das Wichtigste auf einen Blick

Konflikte sind unvermeidbar

Sobald mehrere Geräte offline denselben Datensatz bearbeiten, entsteht bei der Synchronisation zwangsläufig ein Konflikt, den die App aktiv behandeln muss.

Last-Write-Wins reicht selten

Reine Zeitstempel-Vergleiche verursachen bei Uhren-Drift stille Datenverluste, besonders bei geschäftskritischen Feldern.

Feldbasiertes Merge reduziert Kollisionen

Wer Konflikte pro Feld statt pro Datensatz behandelt, verliert deutlich seltener unabhängige Änderungen.

Automatik hat Grenzen

Bei hohem Risiko sollte die App eskalieren und den Nutzer aktiv entscheiden lassen, statt zu raten.

11. FAQ: Offline-Sync-Konfliktlösung: Das Wichtigste auf einen Blick

1Was verursacht Synchronisationskonflikte in Offline-First-Apps überhaupt?
Konflikte entstehen, wenn zwei Geräte offline denselben Datensatz von derselben Ausgangsversion aus verändern und beide Änderungen anschließend gegen denselben Server-Zustand synchronisiert werden.
2Warum ist Last-Write-Wins riskant?
Weil die Regel sich auf Client-Zeitstempel verlässt, die durch Uhren-Drift oder verzögerte Synchronisation nicht immer die tatsächliche Reihenfolge der Änderungen widerspiegeln, was zu stillem Datenverlust führen kann.
3Was ist der Unterschied zwischen Last-Write-Wins und feldbasiertem Merge?
Last-Write-Wins entscheidet für den gesamten Datensatz, feldbasiertes Merge vergleicht jedes Feld einzeln und behält unabhängige Änderungen aus beiden Versionen, statt eine komplett zu verwerfen.
4Wann lohnen sich CRDTs für eine React-Native-App?
Vor allem bei kollaborativen Inhalten wie gemeinsam bearbeiteten Notizen oder Zählern, bei denen mathematisch garantierte Konvergenz wichtiger ist als geringer Metadaten-Overhead.
5Wie erkennt ein System einen echten Konflikt statt nur eine spätere Änderung?
Über Versionsvektoren, bei denen jedes Gerät einen eigenen Zähler pro Datensatz führt. Nur wenn zwei Vektoren nebeneinander liegen statt linear aufeinander aufzubauen, handelt es sich um einen echten Konflikt.
6Wann sollte die App den Nutzer aktiv nach der Auflösung fragen?
Immer dann, wenn eine automatische Entscheidung finanzielle oder geschäftskritische Folgen haben könnte, etwa bei Preisen, Rabatten oder Lagerbeständen.
7Unterstützt WatermelonDB Konfliktauflösung von Haus aus?
WatermelonDB liefert eine einfache Last-Write-Wins-Logik im pullChanges/pushChanges-Zyklus, erlaubt aber, einen eigenen Resolver für spezifischere Anforderungen einzuhängen.
8Wie testet man Konfliktszenarien zuverlässig?
Am besten mit Integrationstests, die zwei simulierte Clients denselben Ausgangsdatensatz offline verändern lassen und anschließend beide Änderungen nacheinander gegen denselben Server-Endpunkt schicken.
9Was passiert, wenn Konflikte gar nicht behandelt werden?
Ohne explizite Behandlung überschreibt in der Regel die zuletzt eingehende Anfrage stillschweigend die vorherige, was zu unbemerktem Datenverlust und inkonsistenten Zuständen zwischen Geräten führt.
10Lohnt sich ein Änderungsprotokoll zusätzlich zur Konfliktauflösung?
Ja, ein durchgängiges Änderungsprotokoll dokumentiert jede Konfliktentscheidung nachvollziehbar und dient im Streitfall oder bei einer Support-Anfrage als konkreter Nachweis, was wann warum entschieden wurde.