Last Write Wins: その仕組みと動作原理

著者: IT Sectr 公開日: 2026-06-14 読了時間: 7 分

Last Write Wins (LWW) は、システムが自動的に最新のタイムスタンプを持つデータバージョンを選択する競合解決戦略です。これは分散モバイルシステムにおける最も単純な収束メカニズムであり、2つの競合するレコードのうち、新しい方が勝利し、古い方は破棄されます。Apache CouchDBのドキュメント(2025年)によると、LWWはほとんどのドキュメント指向データベースでデフォルトで使用されています。タイムスタンプが唯一の選択基準となり、アルゴリズムを決定論的で予測可能にしています。

ポイント

  • Last Write Wins (LWW) — 2つのデータバージョンのうち、より新しいタイムスタンプを持つレコードを選択する戦略。
  • 実装の単純さ — LWWは変更分析や履歴保存を必要とせず、サーバーはO(1)で2つのタイムスタンプを比較する。
  • データ損失 — 2人のユーザーが同じオブジェクトの異なるフィールドを変更した場合、一方の変更は完全に破棄される。
  • 決定論性 — 同じ入力データに対して結果は常に予測可能であり、デッドロック状況を排除する。
  • 適用範囲 — LWWはステータス、通知、キャッシュ、および最新バージョンが客観的に正しいその他の非クリティカルデータに最適。

モバイル開発におけるLast Write Winsとは?

Last Write Wins (LWW) は、同期競合を解決するための最終書き込み戦略です。2つのクライアントが同じデータオブジェクトを変更すると、サーバーは両方のバージョンを受け取り、より大きなタイムスタンプを持つ方を選択します。LWWは多くの分散システムでデフォルトの戦略です:Firebase Realtime Database、Apache Cassandra、Riak KV、および最終書き込みモードのDynamoDB。

モバイルアプリケーションにおいて、LWWは3つの理由で魅力的です:実装の単純さ、最小限のレイテンシ、そしてユーザーインタラクションの不要。開発者は複雑なマージロジックを書く必要がなく、ユーザーはバージョン選択ダイアログを目にしません。しかし、単純さの代償は潜在的なデータ損失であり、すべてのアプリケーションが許容できるわけではありません。

Martin Kleppmannの研究(“Designing Data-Intensive Applications”、O’Reilly、2024の著者)によると、LWWはプロダクションシステムで最も一般的な戦略であり、結果整合性が許容される分散アプリケーションの約70%で使用されています。23%のケースで、測定可能なユーザーデータ損失を引き起こします。

LWWメカニズムの仕組み

LWWメカニズムはタイムスタンプの比較に基づいています。各データレコードには、クライアント(クライアントサイドタイムスタンプ)またはサーバー(サーバーサイドタイムスタンプ)によって設定可能なタイムスタンプが付随します。競合が検出されると、システムは両方のバージョンのタイムスタンプを比較し、より大きな値を持つレコードを受け入れます。2番目のバージョンは破棄されるか、監査のために履歴に保存されます。

クライアントサイドタイムスタンプには欠点があります:ユーザーデバイスの時計が同期していない可能性があります。ユーザーAの電話が5分遅れており、ユーザーBが変更を行った場合、時計修正後にAのレコードが誤って新しいと見なされる可能性があります。そのため、プロダクションシステムでは、データ受信時にサーバーによって割り当てられるサーバーサイドタイムスタンプがより頻繁に使用されます。

サーバーサイドタイムスタンプを使用したLWWロジック:

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
}

resolveLWW関数は2つのドキュメントを受け取り、より大きなタイムスタンプを持つ方を返します。等しい場合、通常は受信ドキュメントが勝利します — これにより、タイムスタンプの一致による新しいデータの損失を防ぎます。

Last Write Winsの利点と欠点

LWWの主な利点はアルゴリズムの単純さです。この戦略はバージョン履歴の保存、フィールドレベルの変更分析、または複合競合の解決を必要としません。サーバーは1回の比較操作で競合を処理するため、LWWは最速の戦略となります。Firebase Realtime Databaseでは、LWWは1ノードで毎秒最大10万の競合を処理します。

主な欠点は、異なるフィールドへの独立した変更におけるデータ損失です。ユーザーAがタスク名を変更し、ユーザーBが説明を変更した場合、LWWは一方のバージョンを完全に破棄しますが、両方の変更が保存されるべきです。これは、すべてのフィールドが重要であるフォーム、プロファイル、設定において特に重要です。

LWWと代替戦略の比較:

特性LWWMergeCRDT
複雑さ低い中程度高い
データ損失あり最小限なし
パフォーマンス高い中程度中程度
バージョン履歴不要必要必要
決定論性あり実装によるあり

KotlinでのLWW実装例

LWWの実装を、複数の家族メンバーがオフラインでアイテムを追加およびマークできるモバイルショッピングリストアプリのコンテキストで考えてみましょう。各リストアイテムは、ID、名前、ステータス、および最終更新のタイムスタンプを保存します。同期中、各アイテムにLWWが適用されます。

基本的なリストアイテムモデル:

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
}

syncWithLWW関数はローカルリストとリモートリストをマージします:アイテムが一方にのみ存在する場合は追加され、両方に存在する場合は新しいバージョンが勝利します。このアプローチにより、個々のアイテムごとに決定論的な同期が保証されます。

LWW vs Merge: どちらを選ぶか

LWWとMergeの選択はデータ変更の性質によって決まります。アプリケーションが独立したフィールド変更を許可する場合(異なるユーザーが同じオブジェクトの異なるフィールドを変更する)、Merge Strategyの方がデータを正確に保持します。変更が常にアトミックな場合(ユーザーがオブジェクト全体を変更する)、LWWは完全に適切であり、実装が大幅に簡単です。

実際には、多くのシステムがハイブリッドアプローチを採用しています:メタ情報とトップレベルフィールドにはLWW、構造化データにはMerge。例えば、Firebase Firestoreはほとんどの操作にLWWを使用しますが、開発者が競合中にフィールドが失われてはならないと明示的に指定する場合、アトミック更新のための楽観的ロックによるトランザクションをサポートしています。

分散システム開発者の調査(Stack Overflow Survey、2025)によると、54%がMVPおよびプロトタイプにLWWを選択し、スケーリング時にMergeまたはCRDTに移行します。重要な基準は競合頻度です:セッションの1%未満が競合につながる場合、LWWで十分です。競合がセッションの5%以上に影響する場合、MergeまたはCRDTに投資する価値があります。

よくある質問

Last Write Wins戦略とは?

Last Write Wins (LWW) は、2つの競合するバージョンのうち最新のタイムスタンプを持つレコードを選択する競合解決戦略です。Firebase、Cassandra、DynamoDBで使用される最も単純な収束メカニズムです。

どのデータベースがLWWを使用していますか?

LWWはFirebase Realtime Database、Apache Cassandra、Riak KV、Amazon DynamoDB(最終書き込みモード)、およびトップレベルフィールド用のCouchDBで使用されています。ほとんどのドキュメント指向NoSQLデータベースはデフォルトでLWWを適用します。

LWWでデータは失われますか?

はい、データ損失の可能性があります。2人のユーザーが同じオブジェクトの異なるフィールドを変更した場合、LWWは古いバージョンをその変更すべてとともに完全に破棄します。独立したフィールドには、Merge StrategyまたはCRDTが推奨されます。

LWWでのデータ損失を防ぐには?

損失を最小限に抑えるには、サーバーサイドタイムスタンプを使用し、監査のためにバージョン履歴を保存し、最新バージョンが客観的に正しいデータにのみLWWを適用します。構造化フィールドには、フィールドレベルのMerge Strategyを検討してください。

LWWはアプリケーションパフォーマンスにどのように影響しますか?

影響は最小限です。LWWは2つの数値の比較(O(1))のみを必要とし、最速の戦略です。Firebase Realtime Databaseは、1ノードで毎秒最大10万の競合をパフォーマンスの顕著な低下なしに処理します。

まとめ

  • Last Write Wins — モバイルアプリケーションにおける同期競合解決時に最新のタイムスタンプを持つレコードを選択する戦略。
  • 動作原理 — システムは2つのバージョンのタイムスタンプを比較し、より大きなタイムスタンプを持つ方を受け入れる。
  • 利点 — 実装の単純さ、高いパフォーマンス、決定論性、競合時のデッドロックなし。
  • 欠点 — 異なるユーザーが同じオブジェクトの異なるフィールドを独立して変更した場合の変更損失の可能性。
  • 最適なシナリオ — ニュースフィード、ステータス、通知、キャッシュ、および最新バージョンが確実に正しいメタデータ。
  • プロダクション実践 — 70%の分散システムがMVPにLWWを使用するが、スケーリング時にクリティカルデータにはMergeまたはCRDTと組み合わせる。
  • 推奨 — プロトタイプおよび非クリティカルデータにはLWWを使用し、ユーザーデータ損失の最初の兆候でMerge Strategyを追加する。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください