Last Write Wins (LWW) là một chiến lược giải quyết xung đột trong đó hệ thống tự động chọn phiên bản dữ liệu có dấu thời gian mới nhất. Đây là cơ chế hội tụ đơn giản nhất trong các hệ thống di động phân tán: trong hai bản ghi cạnh tranh, bản mới hơn thắng và bản cũ bị loại bỏ. Theo tài liệu Apache CouchDB, 2025, LWW được sử dụng mặc định trong hầu hết các cơ sở dữ liệu hướng tài liệu. Dấu thời gian đóng vai trò là tiêu chí lựa chọn duy nhất, làm cho thuật toán mang tính quyết định và có thể dự đoán trước.
Điểm chính
Last Write Wins (LWW) là một chiến lược ghi cuối cùng để giải quyết xung đột đồng bộ hóa. Khi hai máy khách sửa đổi cùng một đối tượng dữ liệu, máy chủ nhận được cả hai phiên bản và chọn phiên bản có dấu thời gian lớn hơn. LWW là chiến lược mặc định trong nhiều hệ thống phân tán: Firebase Realtime Database, Apache Cassandra, Riak KV và DynamoDB ở chế độ ghi cuối cùng.
Trong ứng dụng di động, LWW hấp dẫn vì ba lý do: đơn giản khi triển khai, độ trễ tối thiểu và không cần tương tác với người dùng. Nhà phát triển không cần viết logic hợp nhất phức tạp và người dùng không thấy hộp thoại chọn phiên bản. Tuy nhiên, cái giá của sự đơn giản là nguy cơ mất dữ liệu — điều mà không phải ứng dụng nào cũng có thể chấp nhận.
Theo nghiên cứu của Martin Kleppmann (tác giả “Designing Data-Intensive Applications”, O’Reilly, 2024), LWW là chiến lược phổ biến nhất trong các hệ thống sản xuất, được sử dụng trong khoảng 70% ứng dụng phân tán nơi tính nhất quán cuối cùng được chấp nhận. Trong 23% trường hợp, nó dẫn đến mất dữ liệu người dùng có thể đo lường được.
Cơ chế LWW dựa trên việc so sánh dấu thời gian. Mỗi bản ghi dữ liệu đi kèm với một dấu thời gian có thể được thiết lập bởi máy khách (dấu thời gian phía máy khách) hoặc máy chủ (dấu thời gian phía máy chủ). Khi phát hiện xung đột, hệ thống so sánh dấu thời gian của cả hai phiên bản và chấp nhận bản ghi có giá trị lớn hơn. Phiên bản thứ hai bị loại bỏ hoặc được lưu trong lịch sử để kiểm toán.
Dấu thời gian phía máy khách có một nhược điểm: đồng hồ trên thiết bị người dùng có thể không đồng bộ. Nếu điện thoại của người dùng A chậm 5 phút và người dùng B đã thực hiện thay đổi, bản ghi của A có thể bị coi là mới hơn một cách sai lầm sau khi đồng hồ được chỉnh sửa. Do đó, các hệ thống sản xuất thường sử dụng dấu thời gian phía máy chủ do máy chủ chỉ định khi nhận dữ liệu.
Logic LWW với dấu thời gian phía máy chủ:
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
}
Hàm resolveLWW nhận hai tài liệu và trả về tài liệu có dấu thời gian lớn hơn. Khi bằng nhau, tài liệu đến thường thắng — điều này đảm bảo rằng dữ liệu mới không bị mất do dấu thời gian trùng nhau.
Ưu điểm chính của LWW là sự đơn giản về thuật toán. Chiến lược không yêu cầu lưu trữ lịch sử phiên bản, phân tích thay đổi ở cấp trường hay giải quyết xung đột phức hợp. Máy chủ xử lý xung đột bằng một thao tác so sánh duy nhất, khiến LWW trở thành chiến lược nhanh nhất. Trong Firebase Realtime Database, LWW xử lý tới 100 nghìn xung đột mỗi giây trên một nút.
Nhược điểm chính là mất dữ liệu khi thay đổi độc lập trên các trường khác nhau. Nếu người dùng A thay đổi tên nhiệm vụ và người dùng B thay đổi mô tả, LWW loại bỏ hoàn toàn một phiên bản, mặc dù cả hai thay đổi đều cần được lưu giữ. Điều này đặc biệt quan trọng đối với biểu mẫu, hồ sơ và cấu hình nơi mỗi trường đều có giá trị.
So sánh LWW với các chiến lược thay thế:
| Đặc điểm | LWW | Merge | CRDT |
|---|---|---|---|
| Độ phức tạp | Thấp | Trung bình | Cao |
| Mất dữ liệu | Có | Tối thiểu | Không |
| Hiệu năng | Cao | Trung bình | Trung bình |
| Lịch sử phiên bản | Không yêu cầu | Yêu cầu | Yêu cầu |
| Tính quyết định | Có | Phụ thuộc vào triển khai | Có |
Hãy xem xét triển khai LWW trong bối cảnh ứng dụng danh sách mua sắm di động nơi nhiều thành viên trong gia đình có thể thêm và đánh dấu các mục ngoại tuyến. Mỗi mục danh sách lưu trữ ID, tên, trạng thái và dấu thời gian của lần cập nhật cuối cùng. Trong quá trình đồng bộ hóa, LWW được áp dụng cho từng mục.
Mô hình mục danh sách cơ bản:
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
}
Hàm syncWithLWW hợp nhất danh sách cục bộ và từ xa: nếu mục chỉ tồn tại ở một bên, nó được thêm vào; nếu tồn tại ở cả hai bên, phiên bản mới hơn thắng. Cách tiếp cận này đảm bảo đồng bộ hóa mang tính quyết định cho từng mục riêng lẻ.
Sự lựa chọn giữa LWW và Merge được xác định bởi bản chất của việc sửa đổi dữ liệu. Nếu ứng dụng cho phép thay đổi trường độc lập (những người dùng khác nhau thay đổi các trường khác nhau của cùng một đối tượng), Merge Strategy bảo toàn dữ liệu chính xác hơn. Nếu các thay đổi luôn mang tính nguyên tử (người dùng thay đổi toàn bộ đối tượng), LWW hoàn toàn phù hợp và đơn giản hơn nhiều khi triển khai.
Trong thực tế, nhiều hệ thống sử dụng cách tiếp cận kết hợp: LWW cho thông tin meta và các trường cấp cao, Merge cho dữ liệu có cấu trúc. Firebase Firestore, ví dụ, sử dụng LWW cho hầu hết các thao tác nhưng hỗ trợ giao dịch với khóa lạc quan cho các cập nhật nguyên tử khi nhà phát triển chỉ định rõ rằng một trường không được mất trong xung đột.
Theo một khảo sát với các nhà phát triển hệ thống phân tán (Stack Overflow Survey, 2025), 54% chọn LWW cho MVP và nguyên mẫu, chuyển sang Merge hoặc CRDT khi mở rộng quy mô. Tiêu chí chính là tần suất xung đột: nếu dưới 1% phiên dẫn đến xung đột, LWW là quá đủ. Nếu xung đột ảnh hưởng đến hơn 5% phiên, đáng để đầu tư vào Merge hoặc CRDT.
Câu hỏi thường gặp
Last Write Wins (LWW) là một chiến lược giải quyết xung đột trong đó từ hai phiên bản cạnh tranh, bản ghi có dấu thời gian mới nhất được chọn. Đây là cơ chế hội tụ đơn giản nhất được sử dụng trong Firebase, Cassandra và DynamoDB.
LWW được sử dụng trong Firebase Realtime Database, Apache Cassandra, Riak KV, Amazon DynamoDB (chế độ ghi cuối cùng) và CouchDB cho các trường cấp cao. Hầu hết cơ sở dữ liệu NoSQL hướng tài liệu áp dụng LWW theo mặc định.
Có, có thể mất dữ liệu. Nếu hai người dùng thay đổi các trường khác nhau của cùng một đối tượng, LWW loại bỏ hoàn toàn phiên bản cũ hơn cùng với tất cả các thay đổi của nó. Đối với các trường độc lập, Merge Strategy hoặc CRDT được ưu tiên hơn.
Để giảm thiểu tổn thất, hãy sử dụng dấu thời gian phía máy chủ, lưu trữ lịch sử phiên bản để kiểm toán và chỉ áp dụng LWW cho dữ liệu nơi phiên bản mới nhất đúng một cách khách quan. Đối với các trường có cấu trúc, hãy cân nhắc Merge Strategy ở cấp trường.
Tác động là tối thiểu. LWW chỉ cần so sánh hai giá trị số (O(1)), khiến nó trở thành chiến lược nhanh nhất. Firebase Realtime Database xử lý tới 100 nghìn xung đột mỗi giây trên một nút mà không làm giảm hiệu năng đáng kể.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm