Last Write Wins: co to jest, mechanizm i zasada działania

Autor: IT Sectr Opublikowano: 2026-06-14 Czas czytania: 7 min

Last Write Wins (LWW) — strategia rozwiązywania konfliktów, w której system automatycznie wybiera wersję danych z najpóźniejszym znacznikiem czasu. Jest to najprostszy mechanizm konwergencji w rozproszonych systemach mobilnych: z dwóch konkurujących zapisów zwycięża nowszy, a starszy jest odrzucany. Według Apache CouchDB documentation, 2025, LWW jest domyślnie używany w większości dokumentowych baz danych. Znacznik czasu jest jedynym kryterium wyboru, co czyni algorytm deterministycznym i przewidywalnym.

Najważniejsze

  • Last Write Wins (LWW) — strategia, w której z dwóch wersji danych wybierany jest zapis z późniejszym znacznikiem czasu.
  • Prostota implementacji — LWW nie wymaga analizy zmian ani przechowywania historii, serwer porównuje dwa znaczniki czasu w O(1).
  • Utrata danych — jeśli dwóch użytkowników zmieniło różne pola tego samego obiektu, zmiany jednego zostaną całkowicie odrzucone.
  • Determinizm — przy tych samych danych wejściowych wynik jest zawsze przewidywalny, co eliminuje sytuacje zakleszczenia.
  • Zakres zastosowania — LWW jest optymalny dla statusów, powiadomień, pamięci podręcznej i innych niekrytycznych danych, gdzie ostatnia wersja jest obiektywnie poprawna.

Czym jest Last Write Wins w rozwoju mobilnym?

Last Write Wins (LWW) — to strategia ostatniego zapisu przy rozwiązywaniu konfliktów synchronizacji. Gdy dwaj klienci zmieniają ten sam obiekt danych, serwer otrzymuje obie wersje i wybiera tę z większym znacznikiem czasu (timestamp). LWW jest domyślną strategią w wielu systemach rozproszonych: Firebase Realtime Database, Apache Cassandra, Riak KV i DynamoDB w trybie ostatniego zapisu.

W aplikacjach mobilnych LWW jest atrakcyjny z trzech powodów: prostota implementacji, minimalne opóźnienie i brak interakcji z użytkownikiem. Deweloper nie musi pisać złożonej logiki łączenia, a użytkownik nie widzi okien dialogowych wyboru wersji. Jednak ceną za prostotę jest potencjalna utrata danych, na którą nie wszystkie aplikacje mogą sobie pozwolić.

Według badań Martina Kleppmanna (autor „Designing Data-Intensive Applications”, O’Reilly, 2024), LWW jest najczęściej stosowaną strategią w systemach produkcyjnych, używaną w około 70% aplikacji rozproszonych, w których dopuszczalna jest ostateczna spójność (eventual consistency). W 23% przypadków prowadzi to do wymiernej utraty danych użytkowników.

Jak działa mechanizm LWW

Mechanizm LWW opiera się na porównywaniu znaczników czasu. Każdy zapis danych zawiera znacznik czasu, który może być ustawiony przez klienta (client-side timestamp) lub serwer (server-side timestamp). Po wykryciu konfliktu system porównuje znaczniki czasu obu wersji i akceptuje zapis z większą wartością. Druga wersja jest albo odrzucana, albo zapisywana w historii do audytu.

Client-side timestamp ma wadę: zegary na urządzeniach użytkowników mogą być zdesynchronizowane. Jeśli telefon użytkownika A spóźnia się o 5 minut, a użytkownik B wprowadzi zmiany, zapis A może zostać błędnie uznany za nowszy po naprawieniu zegara. Dlatego systemy produkcyjne częściej używają server-side timestamp, nadawanego przez serwer po otrzymaniu danych.

Logika LWW z server-side timestamp:

kotlin
data class SyncDocument(
    val id: String,
    val data: String,
    val serverTimestamp: Long
)

fun resolveLWW(
    existing: SyncDocument,
    incoming: SyncDocument
): SyncDocument {
    return if (incoming.serverTimestamp >= existing.serverTimestamp)
        incoming
    else
        existing
}

Funkcja resolveLWW przyjmuje dwa dokumenty i zwraca ten, którego znacznik czasu jest większy. W przypadku równości zwykle wygrywa dokument przychodzący — gwarantuje to, że nowe dane nie zostaną utracone z powodu zbieżności znaczników.

Zalety i wady Last Write Wins

Główna zaleta LWW to prostota algorytmiczna. Strategia nie wymaga przechowywania historii wersji, analizy zmian na poziomie pól ani rozwiązywania złożonych konfliktów. Serwer przetwarza konflikt w jednej operacji porównania, co czyni LWW najszybszą strategią. W Firebase Realtime Database LWW obsługuje do 100 tysięcy konfliktów na sekundę na jednym węźle.

Główna wada — utrata danych przy niezależnych zmianach różnych pól. Jeśli użytkownik A zmienił nazwę zadania, a użytkownik B — opis, LWW odrzuci jedną z wersji w całości, mimo że obie zmiany powinny być zachowane. Jest to szczególnie krytyczne dla formularzy, profilów i konfiguracji, gdzie każde pole ma znaczenie.

Porównanie LWW z alternatywnymi strategiami:

CechaLWWMergeCRDT
ZłożonośćNiskaŚredniaWysoka
Utrata danychTakMinimalnaNie
WydajnośćWysokaŚredniaŚrednia
Historia wersjiNiewymaganaWymaganaWymagana
DeterminizmTakZależy od implementacjiTak

Przykłady implementacji LWW w Kotlinie

Rozważmy implementację LWW w kontekście aplikacji mobilnej do listy zakupów, gdzie kilku członków rodziny może dodawać i oznaczać produkty offline. Każdy element listy przechowuje ID, nazwę, status i znacznik czasu ostatniej aktualizacji. Podczas synchronizacji stosowany jest LWW dla każdego elementu.

Podstawowy model elementu listy:

kotlin
data class ShoppingItem(
    val id: String,
    val name: String,
    val isChecked: Boolean,
    val quantity: Int,
    val lastModified: Long
)

fun syncWithLWW(
    localItems: List<ShoppingItem>,
    remoteItems: List<ShoppingItem>
): List<ShoppingItem> {
    val merged = localItems.toMutableList()

    remoteItems.forEach { remote ->
        val index = merged.indexOfFirst { it.id == remote.id }
        if (index == -1) {
            merged.add(remote)
        } else {
            val local = merged[index]
            merged[index] = if (remote.lastModified >= local.lastModified)
                remote
            else
                local
        }
    }
    return merged
}

Funkcja syncWithLWW łączy lokalną i zdalną listę: jeśli element istnieje tylko po jednej stronie — jest dodawany, jeśli po obu — wygrywa nowsza wersja. To podejście zapewnia deterministyczną synchronizację dla każdego pojedynczego elementu.

LWW kontra Merge — co wybrać

Wybór między LWW a Merge zależy od charakteru modyfikacji danych. Jeśli aplikacja dopuszcza niezależne zmiany pól (różni użytkownicy zmieniają różne pola tego samego obiektu), Merge Strategy dokładniej zachowa dane. Jeśli zmiany są zawsze atomowe (użytkownik zmienia cały obiekt), LWW jest w pełni adekwatny i znacznie prostszy w implementacji.

W praktyce wiele systemów stosuje podejście hybrydowe: LWW dla meta-informacji i pól górnego poziomu, Merge dla danych strukturalnych. Firebase Firestore na przykład używa LWW dla większości operacji, ale obsługuje transakcje z optymistycznym blokowaniem dla aktualizacji atomowych, gdy deweloper jawnie określi, że pole nie powinno zostać utracone podczas konfliktu.

Według ankiety wśród deweloperów systemów rozproszonych (Stack Overflow Survey, 2025), 54% wybiera LWW dla MVP i prototypów, przechodząc na Merge lub CRDT na etapie skalowania. Kluczowym kryterium jest częstotliwość konfliktów: jeśli mniej niż 1% sesji prowadzi do konfliktów, LWW jest w pełni wystarczający. Jeśli konflikty dotyczą ponad 5% sesji, warto zainwestować w Merge lub CRDT.

Często zadawane pytania

Czym jest strategia Last Write Wins?

Last Write Wins (LWW) — strategia rozwiązywania konfliktów, w której z dwóch konkurujących wersji wybierany jest zapis z najpóźniejszym znacznikiem czasu. Jest to najprostszy mechanizm konwergencji używany w Firebase, Cassandra i DynamoDB.

W jakich bazach danych używany jest LWW?

LWW jest używany w Firebase Realtime Database, Apache Cassandra, Riak KV, Amazon DynamoDB (tryb ostatniego zapisu) i CouchDB dla pól górnego poziomu. Większość dokumentowych baz danych NoSQL stosuje LWW domyślnie.

Czy można stracić dane przy LWW?

Tak, utrata danych jest możliwa. Jeśli dwóch użytkowników zmieniło różne pola tego samego obiektu, LWW odrzuca starszą wersję w całości wraz ze wszystkimi jej zmianami. Dla niezależnych pól preferowana jest Merge Strategy lub CRDT.

Jak uniknąć utraty danych przy LWW?

Aby zminimalizować straty używaj server-side timestamp, przechowuj historię wersji do audytu i stosuj LWW tylko dla tych danych, gdzie ostatnia wersja jest obiektywnie poprawna. Dla pól strukturalnych rozważ Merge Strategy na poziomie pól.

Jak LWW wpływa na wydajność aplikacji?

Wpływ jest minimalny. LWW wymaga tylko porównania dwóch wartości liczbowych (O(1)), co czyni go najszybszą strategią. Firebase Realtime Database obsługuje do 100 tysięcy konfliktów na sekundę na jednym węźle bez zauważalnego spadku wydajności.

Podsumowanie

  • Last Write Wins — strategia wyboru ostatniego w czasie zapisu przy rozwiązywaniu konfliktów synchronizacji w aplikacjach mobilnych.
  • Zasada działania — system porównuje znaczniki czasu dwóch wersji i akceptuje tę z większym timestamp.
  • Zalety — prostota implementacji, wysoka wydajność, determinizm i brak sytuacji zakleszczenia przy konfliktach.
  • Wady — możliwa utrata zmian przy niezależnej modyfikacji różnych pól tego samego obiektu przez różnych użytkowników.
  • Optymalne scenariusze — kanał informacyjny, statusy, powiadomienia, pamięć podręczna i metadane, gdzie ostatnia wersja jest z góry poprawna.
  • Praktyka produkcyjna — 70% systemów rozproszonych używa LWW dla MVP, ale przy skalowaniu łączą go z Merge lub CRDT dla krytycznych danych.
  • Zalecenie — używaj LWW dla prototypów i niekrytycznych danych, dodawaj Merge Strategy przy pierwszych oznakach utraty danych użytkowników.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również