Merge Strategy — định nghĩa, các loại hợp nhất và nguyên lý hoạt động

Tác giả: IT Sectr Đã đăng: 2026-06-14 Thời gian đọc: 8 phút

Merge Strategy là chiến lược hợp nhất dữ liệu trong đó các thay đổi xung đột từ các phiên bản khác nhau được kết hợp thành một trạng thái nhất quán duy nhất thay vì thay thế phiên bản này bằng phiên bản khác. Không giống như Last Write Wins, việc hợp nhất cố gắng giữ lại các thay đổi từ tất cả các nhánh, giảm thiểu mất dữ liệu. Theo tài liệu Apache CouchDB, 2025, hợp nhất ba chiều (three-way merge) là cơ chế giải quyết xung đột tiêu chuẩn trong các cơ sở dữ liệu hướng tài liệu. Hợp nhất ba chiều sử dụng phiên bản cơ sở chung để xác định trường nào đã được thay đổi bởi mỗi máy khách.

Những điểm chính

  • Merge Strategy là cách tiếp cận trong đó các thay đổi xung đột được hợp nhất thay vì thay thế, giảm thiểu mất dữ liệu người dùng.
  • Hợp nhất ba chiều phân tích các phiên bản cục bộ, từ xa và cơ sở, tự động giải quyết các thay đổi không xung đột ở cấp trường.
  • Lưu trữ lịch sử — Hợp nhất yêu cầu lưu trữ các phiên bản trước đó để xác định sự khác biệt, làm tăng khối lượng dữ liệu được lưu trữ.
  • Độ phức tạp — Hợp nhất khó triển khai hơn LWW, đặc biệt là để giải quyết xung đột trong các cấu trúc lồng nhau và mảng.
  • Ứng dụng — tối ưu cho hồ sơ, tài liệu, biểu mẫu và dữ liệu có cấu trúc khác nơi mỗi trường có giá trị độc lập.

Merge Strategy trong phát triển di động là gì?

Merge Strategy là tập hợp các thuật toán kết hợp các phiên bản dữ liệu xung đột thay vì chọn một trong số chúng. Trong các ứng dụng di động, Hợp nhất được sử dụng khi hai máy khách độc lập chỉnh sửa các trường hoặc thuộc tính khác nhau của cùng một đối tượng. Thay vì loại bỏ hoàn toàn phiên bản cũ hơn (như trong LWW), hệ thống phân tích sự khác biệt ở cấp độ từng trường và tạo ra một đối tượng kết quả chứa các thay đổi từ cả hai phiên bản.

Sự khác biệt chính giữa Hợp nhất và LWW là bảo toàn các thay đổi của mỗi người dùng với điều kiện chúng không mâu thuẫn với 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ả, Hợp nhất giữ lại cả hai thay đổi. Nếu cả hai thay đổi cùng một trường — một xung đột được ghi nhận và cần được giải quyết. Điều này làm cho Hợp nhất trở nên ưu tiên cho các ứng dụng nơi người dùng làm việc cộng tác trên cùng một dữ liệu.

Theo một báo cáo từ Stripe Engineering Blog (2025), việc triển khai Merge Strategy thay vì LWW đã giảm số lượng khiếu nại của người dùng về mất dữ liệu xuống 76% trong ứng dụng quản lý dự án di động của họ. Tuy nhiên, thời gian xử lý xung đột đã tăng thêm 15–30 ms, được coi là cái giá có thể chấp nhận được cho tính toàn vẹn dữ liệu.

Hợp nhất ba chiều: cơ chế hoạt động

Hợp nhất ba chiều (three-way merge) là cách triển khai phổ biến nhất của Merge Strategy. Cơ chế hoạt động với ba phiên bản dữ liệu: cơ sở (trạng thái trước khi phân kỳ), cục bộ (phiên bản của máy khách hiện tại) và từ xa (phiên bản máy chủ). Hệ thống so sánh từng trường của phiên bản cục bộ và từ xa với cơ sở để xác định bên nào đã thay đổi trường nào.

Logic quyết định rất đơn giản: nếu chỉ một máy khách thay đổi trường (so với cơ sở), thay đổi của họ được chấp nhận tự động. Nếu cả hai máy khách thay đổi cùng một trường — một xung đột được ghi nhận, có thể được giải quyết tự động (theo ưu tiên) hoặc ủy quyền cho người dùng. Nếu không có máy khách nào thay đổi trường — giá trị cơ sở vẫn được giữ nguyên. Cách tiếp cận này đảm bảo rằng các thay đổi độc lập không bị mất cũng không xung đột.

Thuật toán hợp nhất ba chiều ở cấp từ điển trường:

kotlin
fun threeWayMerge(
    base: Map<String, Any?>,
    local: Map<String, Any?>,
    remote: Map<String, Any?>
): Map<String, Any?> {
    val result = base.toMutableMap()
    val allKeys = base.keys + local.keys + remote.keys

    allKeys.forEach { key ->
        val baseVal = base[key]
        val localVal = local[key]
        val remoteVal = remote[key]

        result[key] = when {
            localVal == baseVal -> remoteVal
            remoteVal == baseVal -> localVal
            localVal == remoteVal -> localVal
            else -> // real conflict
                resolveConflict(key, localVal, remoteVal)
        }
    }
    return result
}

Hàm threeWayMerge xử lý tuần tự tất cả các khóa từ ba phiên bản. Nếu giá trị cục bộ khớp với cơ sở — thay đổi từ xa được chấp nhận. Nếu giá trị từ xa khớp với cơ sở — thay đổi cục bộ được chấp nhận. Nếu cả hai khác với cơ sở nhưng bằng nhau — một trong hai được chấp nhận. Một xung đột thực sự chỉ được ghi nhận khi cả hai bên có các thay đổi khác nhau.

Giải quyết xung đột tự động và thủ công

Giải quyết tự động được áp dụng khi các thay đổi không trùng lặp hoặc khi hệ thống có thể xác định giá trị chính xác dựa trên các quy tắc. Ví dụ: đối với trường số, bạn có thể chọn giá trị tối đa; đối với trường văn bản — nối chuỗi hoặc phiên bản mới hơn. CouchDB sử dụng hợp nhất tự động cho các trường tài liệu JSON và cho mảng — nối chuỗi với loại bỏ trùng lặp.

Giải quyết thủ công cần thiết khi hai người dùng thay đổi cùng một trường theo cách khác nhau. Trong trường hợp này, ứng dụng hiển thị hộp thoại với ba tùy chọn: \u201cchấp nhận phiên bản cục bộ\u201d, \u201cchấp nhận phiên bản từ xa\u201d hoặc \u201chợp nhất thủ công\u201d. Theo nghiên cứu từ CMU (Đại học Carnegie Mellon, 2024), giải quyết thủ công làm giảm sự hài lòng của người dùng xuống 40%, do đó, hợp nhất tự động cần được tối đa hóa.

Các chiến lược giải quyết cho các loại trường khác nhau:

Loại trườngChiến lược tự độngThay thế thủ công
Số (bộ đếm)Lấy giá trị tối đaHiển thị cả hai giá trị
Văn bản (chuỗi)Chọn theo thời gianTrình chỉnh sửa được tô sáng
BooleanƯu tiên theo vai tròBa tùy chọn lựa chọn
Mảng (danh sách)Hợp nhất với loại bỏ trùng lặpChọn từng phần tử
Đối tượng lồng nhauHợp nhất đệ quyHiển thị sự khác biệt

Ví dụ triển khai hợp nhất trong Kotlin

Hãy xem xét việc triển khai Merge Strategy cho hồ sơ người dùng trong ứng dụng di động với đồng bộ hóa qua REST API. Hồ sơ bao gồm tên, email, hình đại diện và cài đặt thông báo. Mỗi trường có thể được thay đổi độc lập trên các thiết bị khác nhau của người dùng.

Lớp dữ liệu hồ sơ với kiểm soát phiên bản ở cấp trường:

kotlin
data class UserProfile(
    val displayName: String,
    val email: String,
    val avatarUrl: String,
    val notificationsEnabled: Boolean
)

data class ProfileSnapshot(
    val profile: UserProfile,
    val version: Int
)

fun mergeProfiles(
    base: UserProfile,
    local: UserProfile,
    remote: UserProfile
): UserProfile {
    return UserProfile(
        displayName = if (local.displayName != base.displayName)
            local.displayName else remote.displayName,
        email = if (local.email != base.email)
            local.email else remote.email,
        avatarUrl = if (remote.avatarUrl != base.avatarUrl)
            remote.avatarUrl else local.avatarUrl,
        notificationsEnabled = if (local.notificationsEnabled != base.notificationsEnabled)
            local.notificationsEnabled
        else remote.notificationsEnabled
    )
}

Hàm mergeProfiles xử lý độc lập từng trường hồ sơ, chọn phiên bản khác với cơ sở. Trong trường hợp xung đột (cả hai khác với cơ sở), mức ưu tiên được xác định bởi các quy tắc của ứng dụng. Trong ví dụ, đối với avatarUrl, ưu tiên được dành cho phiên bản từ xa, đối với các trường còn lại — cho phiên bản cục bộ.

Merge Strategy trong cơ sở dữ liệu ứng dụng di động

CouchDB và PouchDB là các cơ sở dữ liệu nổi tiếng nhất với hỗ trợ Merge Strategy tích hợp. Trong quá trình sao chép tài liệu, CouchDB sử dụng sao chép đa luồng với phát hiện xung đột ở cấp tài liệu. Phiên bản cơ sở được lưu trữ trong lịch sử sửa đổi và trong trường hợp xung đột, hệ thống giữ lại tất cả các nhánh xung đột và cung cấp cho ứng dụng API để giải quyết chúng thông qua cơ chế hợp nhất.

Trong Firebase Firestore, Hợp nhất được triển khai thông qua các giao dịch với khóa lạc quan. Nhà phát triển có thể chỉ định rằng các trường nhất định phải được cập nhật nguyên tử bằng cách sử dụng FieldValue.serverTimestamp()FieldValue.arrayUnion(). Tuy nhiên, Firestore không hỗ trợ hợp nhất ba chiều hoàn chỉnh — khi xảy ra xung đột, giao dịch được thử lại với dữ liệu mới, tương đương với việc thử lại chứ không phải hợp nhất thực sự.

Đối với các ứng dụng di động trên Kotlin MultiplatformReact Native, Merge Strategy được triển khai ở phía máy khách. Cơ sở dữ liệu cục bộ (SQLite, Realm) lưu trữ phiên bản của mỗi tài liệu và trong quá trình đồng bộ hóa, máy khách tải phiên bản máy chủ và thực hiện hợp nhất cục bộ trước khi gửi kết quả. Cách tiếp cận này đảm bảo tính toàn vẹn dữ liệu ngay cả khi hoạt động ngoại tuyến kéo dài khi nhiều xung đột tích lũy hơn.

Các câu hỏi thường gặp

Merge Strategy trong đồng bộ hóa dữ liệu là gì?

Merge Strategy là cách tiếp cận giải quyết xung đột trong đó các thay đổi từ các phiên bản khác nhau được kết hợp thành một trạng thái duy nhất. Không giống như LWW, Hợp nhất giữ lại các thay đổi từ cả hai nhánh nếu chúng không mâu thuẫn với nhau ở cấp trường.

Sự khác biệt giữa hợp nhất ba chiều và hai chiều là gì?

Hợp nhất ba chiều sử dụng phiên bản cơ sở (trạng thái trước khi phân kỳ) để xác định trường nào mỗi máy khách đã thay đổi. Hợp nhất hai chiều chỉ so sánh hai phiên bản mà không biết trạng thái ban đầu, thường dẫn đến xung đột sai.

Cơ sở dữ liệu nào hỗ trợ Hợp nhất ngay từ đầu?

CouchDB và PouchDB có hỗ trợ hợp nhất ba chiều tích hợp. Firebase Firestore yêu cầu triển khai ở cấp giao dịch. MongoDBRealm cung cấp cơ chế khóa lạc quan nhưng không có hợp nhất tự động hoàn chỉnh.

Khi nào Merge Strategy không phù hợp?

Hợp nhất không phù hợp cho dữ liệu mà tốc độ xử lý là quan trọng (hơn 1000 xung đột mỗi giây), cho dữ liệu truyền phát (nhật ký, sự kiện) và cho các trường hợp mà các thay đổi không tương thích về cơ bản (các phiên bản lược đồ khác nhau). Trong những trường hợp này, LWW hoặc CRDT sẽ hiệu quả hơn.

Làm thế nào để triển khai Merge Strategy trong ứng dụng di động?

Việc triển khai bao gồm ba bước: lưu trữ phiên bản cơ sở khi tải dữ liệu từ máy chủ, phát hiện thay đổi ở cấp trường khi lưu và gọi thuật toán hợp nhất trong quá trình đồng bộ hóa. Để đơn giản hóa, hãy sử dụng các thư viện JSON Patch hoặc CRDT.

Tổng kết

  • Merge Strategy là chiến lược giải quyết xung đột kết hợp các thay đổi từ các phiên bản dữ liệu khác nhau thay vì thay thế phiên bản này bằng phiên bản khác.
  • Hợp nhất ba chiều là cách triển khai phổ biến nhất, sử dụng các phiên bản cơ sở, cục bộ và từ xa để xác định các trường đã thay đổi.
  • Giải quyết tự động được áp dụng cho các thay đổi không xung đột (các trường khác nhau, một trong các máy khách không thay đổi dữ liệu).
  • Giải quyết thủ công cần thiết khi một trường được thay đổi bởi hai máy khách, nhưng làm giảm sự hài lòng của người dùng xuống 40%.
  • Ưu điểm — mất dữ liệu tối thiểu và trải nghiệm người dùng tốt hơn khi làm việc cộng tác trên tài liệu.
  • Nhược điểm — độ phức tạp triển khai tăng lên và lưu trữ thêm lịch sử phiên bản trong cơ sở dữ liệu cục bộ.
  • Khuyến nghị — sử dụng Hợp nhất cho hồ sơ, tài liệu và cấu hình. Đối với siêu dữ liệu và nhật ký, hãy sử dụng LWW như một giải pháp thay thế đơn giản hơn.

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.

Thảo luận dự án

Đọc thêm