Last Write Wins (LWW) — konfliktusmegoldó stratégia, amelyben a rendszer automatikusan a legkésőbbi időbélyeggel rendelkező adatváltozatot választja ki. Ez a legegyszerűbb konvergenciamechanizmus elosztott mobil rendszerekben: két versengő rekord közül az újabb nyer, a régebbi pedig eldobásra kerül. A Apache CouchDB documentation, 2025 szerint az LWW alapértelmezésben használatos a legtöbb dokumentumorientált adatbázisban. Az időbélyeg az egyetlen kiválasztási kritérium, ami az algoritmust determinisztikussá és előrejelezhetővé teszi.
Főbb pontok
Last Write Wins (LWW) — az utolsó írás stratégiája a szinkronizációs konfliktusok megoldásakor. Amikor két kliens módosítja ugyanazt az adatobjektumot, a szerver mindkét verziót megkapja és kiválasztja a nagyobb időbélyeggel (timestamp) rendelkezőt. Az LWW alapértelmezett stratégia számos elosztott rendszerben: Firebase Realtime Database, Apache Cassandra, Riak KV és DynamoDB az utolsó írás módban.
A mobilalkalmazásokban az LWW három okból vonzó: implementáció egyszerűsége, minimális késleltetés és a felhasználói interakció hiánya. A fejlesztőnek nem kell összetett összefűzési logikát írnia, a felhasználó pedig nem lát verzióválasztó párbeszédablakokat. Az egyszerűség ára azonban a potenciális adatvesztés, amelyet nem minden alkalmazás engedhet meg magának.
Martin Kleppmann kutatása szerint (a „Designing Data-Intensive Applications” szerzője, O’Reilly, 2024), az LWW a legelterjedtebb stratégia a termelési rendszerekben, amelyet az elosztott alkalmazások körülbelül 70%-ában használnak, ahol az eventual consistency elfogadható. Az esetek 23%-ában ez mérhető felhasználói adatvesztéshez vezet.
Az LWW mechanizmus az időbélyegek összehasonlításán alapul. Minden adatrekordhoz tartozik egy timestamp, amelyet a kliens (client-side timestamp) vagy a szerver (server-side timestamp) állíthat be. Konfliktus észlelésekor a rendszer összehasonlítja mindkét verzió időbélyegét és elfogadja a nagyobb értékű rekordot. A második verzió vagy eldobásra kerül, vagy a történetben marad auditálási célokra.
A client-side timestamp hátránnyal rendelkezik: a felhasználók eszközeinek órái eltérhetnek egymástól. Ha az A felhasználó telefonja 5 percet késik, és a B felhasználó módosításokat végez, A rekordja az óra javítása után tévesen újabbnak tekinthető. Ezért a termelési rendszerek gyakrabban használják a server-side timestamp-et, amelyet a szerver rendel hozzá az adatok fogadásakor.
Az LWW logikája server-side timestamp-tel:
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
}
A resolveLWW függvény két dokumentumot fogad és visszaadja azt, amelyiknek nagyobb a timestamp-je. Egyenlőség esetén általában a beérkező dokumentum nyer — ez garantálja, hogy az új adatok nem vesznek el a bélyegek átfedése miatt.
Az LWW fő előnye az algoritmikus egyszerűség. A stratégia nem igényli a verziótörténet tárolását, a mezőszintű változások elemzését vagy az összetett konfliktusok megoldását. A szerver egyetlen összehasonlítási művelettel dolgozza fel a konfliktust, ami az LWW-t a leggyorsabb stratégiává teszi. A Firebase Realtime Database-ben az LWW másodpercenként akár 100 ezer konfliktust is képes feldolgozni egyetlen csomóponton.
A fő hátrány — adatvesztés a különböző mezők független módosításakor. Ha az A felhasználó megváltoztatta a feladat nevét, a B felhasználó pedig a leírást, az LWW az egyik verziót teljesen eldobja, holott mindkét változtatást meg kellene tartani. Ez különösen kritikus az űrlapok, profilok és konfigurációk esetében, ahol minden mező számít.
Az LWW összehasonlítása alternatív stratégiákkal:
| Jellemző | LWW | Merge | CRDT |
|---|---|---|---|
| Bonyolultság | Alacsony | Közepes | Magas |
| Adatvesztés | Igen | Minimális | Nem |
| Teljesítmény | Magas | Közepes | Közepes |
| Verziótörténet | Nem szükséges | Szükséges | Szükséges |
| Determinizmus | Igen | Függ az implementációtól | Igen |
Tekintsük át az LWW implementációt egy mobil bevásárlólista alkalmazás kontextusában, ahol több családtag offline módon adhat hozzá és jelölhet meg termékeket. A lista minden eleme tárolja az ID-t, nevet, állapotot és az utolsó frissítés időbélyegét. Szinkronizáláskor az LWW minden elemre alkalmazásra kerül.
A listaelem alapmodellje:
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
}
A syncWithLWW függvény összefűzi a helyi és a távoli listákat: ha egy elem csak az egyik oldalon létezik — hozzáadásra kerül, ha mindkét oldalon — az újabb verzió nyer. Ez a megközelítés determinisztikus szinkronizációt biztosít minden egyes elemhez.
Az LWW és Merge közötti választást az adatmódosítás jellege határozza meg. Ha az alkalmazás megengedi a mezők független módosítását (különböző felhasználók ugyanazon objektum különböző mezőit módosítják), a Merge Strategy pontosabban őrzi meg az adatokat. Ha a változtatások mindig atomiak (a felhasználó a teljes objektumot módosítja), az LWW teljesen megfelelő és sokkal egyszerűbben implementálható.
A gyakorlatban sok rendszer hibrid megközelítést alkalmaz: LWW a meta-információk és felső szintű mezők számára, Merge a strukturált adatok számára. A Firebase Firestore például LWW-t használ a legtöbb művelethez, de támogatja az optimista zárolással rendelkező tranzakciókat az atomi frissítésekhez, amikor a fejlesztő kifejezetten megjelöli, hogy egy mező nem veszhet el konfliktus esetén.
Az elosztott rendszerek fejlesztőinek felmérése szerint (Stack Overflow Survey, 2025), 54% választja az LWW-t MVP-hez és prototípusokhoz, áttérve Merge-re vagy CRDT-re a skálázási fázisban. A kulcskritérium a konfliktusok gyakorisága: ha a munkamenetek kevesebb mint 1%-a vezet konfliktushoz, az LWW bőven elegendő. Ha a konfliktusok a munkamenetek több mint 5%-t érintik, érdemes Merge-be vagy CRDT-be fektetni.
Gyakran ismételt kérdések
Last Write Wins (LWW) — konfliktusmegoldó stratégia, amelyben két versengő verzió közül a legkésőbbi időbélyeggel rendelkező rekord kerül kiválasztásra. Ez a legegyszerűbb konvergenciamechanizmus, amelyet Firebase-ben, Cassandra-ban és DynamoDB-ben használnak.
Az LWW-t használják a Firebase Realtime Database-ben, Apache Cassandra-ban, Riak KV-ban, Amazon DynamoDB-ben (utolsó írás mód) és a CouchDB-ben a felső szintű mezőkhöz. A legtöbb dokumentumorientált NoSQL adatbázis alapértelmezésben LWW-t alkalmaz.
Igen, adatvesztés lehetséges. Ha két felhasználó ugyanazon objektum különböző mezőit módosította, az LWW a régebbi verziót teljes egészében eldobja az összes változtatásával együtt. Független mezők esetén a Merge Strategy vagy a CRDT előnyösebb.
A veszteségek minimalizálása érdekében használjon server-side timestamp-et, tárolja a verziótörténetet auditáláshoz, és alkalmazza az LWW-t csak azokra az adatokra, ahol az utolsó verzió objektíven helyes. Strukturált mezőkhöz fontolja meg a Merge Strategy használatát mezőszinten.
A hatás minimális. Az LWW csak két numerikus érték összehasonlítását igényli (O(1)), ami a leggyorsabb stratégiává teszi. A Firebase Realtime Database másodpercenként akár 100 ezer konfliktust is képes feldolgozni egyetlen csomóponton észrevehető teljesítménycsökkenés nélkül.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is