Merge Strategy — strategi penggabungan data di mana perubahan yang bertentangan dari versi yang berbeda digabungkan menjadi satu keadaan yang konsisten alih-alih mengganti satu versi dengan versi lain. Berbeda dengan Last Write Wins, penggabungan berusaha mempertahankan perubahan dari semua cabang, meminimalkan kehilangan data. Menurut Apache CouchDB documentation, 2025, penggabungan tiga arah (three-way merge) adalah mekanisme standar resolusi konflik di basis data berorientasi dokumen. Penggabungan tiga arah menggunakan versi dasar bersama untuk menentukan bidang mana yang diubah oleh setiap klien.
Poin Utama
Merge Strategy — kumpulan algoritma yang menggabungkan versi data yang bertentangan alih-alih memilih salah satunya. Di aplikasi mobile, Merge digunakan ketika dua klien secara independen mengedit bidang atau properti berbeda dari objek yang sama. Alih-alih membuang versi yang lebih lama sepenuhnya (seperti di LWW), sistem menganalisis perbedaan di tingkat bidang individu dan membentuk objek hasil yang berisi perubahan dari kedua versi.
Perbedaan utama Merge dari LWW — mempertahankan perubahan setiap pengguna asalkan tidak saling bertentangan. Jika pengguna A mengubah nama tugas dan pengguna B mengubah deskripsi, Merge akan mempertahankan kedua perubahan. Jika keduanya mengubah bidang yang sama — konflik dicatat yang memerlukan resolusi. Ini membuat Merge lebih disukai untuk aplikasi di mana pengguna bekerja bersama pada data yang sama.
Menurut laporan Stripe Engineering Blog (2025), penerapan Merge Strategy alih-alih LWW mengurangi jumlah keluhan pengguna tentang kehilangan data sebesar 76% di aplikasi manajemen proyek mobile mereka. Namun, waktu pemrosesan konflik meningkat 15–30 ms, yang dianggap sebagai harga yang dapat diterima untuk menjaga informasi.
Penggabungan tiga arah (three-way merge) — implementasi Merge Strategy yang paling umum. Mekanisme ini beroperasi dengan tiga versi data: dasar (base — keadaan sebelum divergensi), lokal (local — versi klien saat ini), dan jarak jauh (remote — versi dari server). Sistem membandingkan setiap bidang dari versi lokal dan jarak jauh dengan versi dasar untuk menentukan pihak mana yang mengubah bidang mana.
Logika pengambilan keputusan sederhana: jika bidang hanya diubah oleh satu klien (relatif terhadap dasar), perubahannya diterima secara otomatis. Jika kedua klien mengubah bidang yang sama — konflik dicatat yang dapat diselesaikan secara otomatis (berdasarkan prioritas) atau diteruskan ke pengguna. Jika tidak ada klien yang mengubah bidang — nilai dasar tetap dipertahankan. Pendekatan ini menjamin bahwa perubahan independen tidak hilang dan tidak menimbulkan konflik.
Algoritma penggabungan tiga arah di tingkat kamus bidang:
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 -> // konflik nyata
resolveConflict(key, localVal, remoteVal)
}
}
return result
}
Fungsi threeWayMerge memproses semua kunci dari tiga versi secara berurutan. Jika nilai lokal cocok dengan nilai dasar — perubahan jarak jauh diterima. Jika nilai jarak jauh cocok dengan nilai dasar — perubahan lokal diterima. Jika keduanya berbeda dari dasar tetapi sama satu sama lain — salah satu diterima. Konflik nyata hanya dicatat ketika ada perubahan berbeda dari kedua sisi.
Resolusi otomatis diterapkan ketika perubahan tidak tumpang tindih atau ketika sistem dapat menentukan nilai yang benar berdasarkan aturan. Misalnya, untuk bidang numerik dapat dipilih nilai maksimum, untuk bidang teks — penggabungan atau versi yang lebih baru. CouchDB menggunakan penggabungan otomatis untuk bidang dokumen JSON, dan untuk array — penggabungan dengan penghapusan duplikat.
Resolusi manual diperlukan ketika dua pengguna telah mengubah bidang yang sama dengan cara berbeda. Dalam hal ini, aplikasi menampilkan dialog dengan tiga opsi: “Terima versi lokal”, “Terima versi jarak jauh” atau “Gabungkan secara manual”. Penulis penelitian CMU (Carnegie Mellon University, 2024) mencatat bahwa resolusi manual mengurangi kepuasan pengguna sebesar 40%, oleh karena itu penggabungan otomatis harus dimaksimalkan.
Strategi resolusi untuk berbagai jenis bidang:
| Jenis Bidang | Strategi Otomatis | Alternatif Manual |
|---|---|---|
| Angka (penghitung) | Ambil maksimum | Tampilkan kedua nilai |
| Teks (string) | Pilih berdasarkan waktu | Editor dengan sorotan |
| Nilai boolean | Prioritas berdasarkan peran | Tiga opsi pilihan |
| Array (daftar) | Penggabungan dengan deduplikasi | Pemilihan elemen per elemen |
| Objek bersarang | Penggabungan rekursif | Tampilkan diff |
Mari kita lihat implementasi Merge Strategy untuk profil pengguna di aplikasi mobile dengan sinkronisasi melalui REST API. Profil berisi nama, email, avatar, dan pengaturan notifikasi. Setiap bidang dapat diubah secara independen di perangkat pengguna yang berbeda.
Kelas data profil dengan versioning di tingkat bidang:
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
)
}
Fungsi mergeProfiles memproses setiap bidang profil secara independen, memilih versi yang berbeda dari versi dasar. Saat konflik (keduanya berbeda dari dasar), prioritas ditentukan oleh aturan aplikasi. Dalam contoh, untuk avatarUrl prioritas diberikan ke versi jarak jauh, untuk bidang lainnya — ke versi lokal.
CouchDB dan PouchDB — basis data paling terkenal dengan dukungan bawaan untuk Merge Strategy. Saat mereplikasi dokumen, CouchDB menggunakan replikasi multi-thread dengan deteksi konflik di tingkat dokumen. Versi dasar disimpan dalam riwayat revisi, dan saat konflik, sistem menyimpan semua cabang yang bertentangan dan menyediakan API bagi aplikasi untuk menyelesaikannya melalui mekanisme penggabungan.
Di Firebase Firestore, Merge diimplementasikan melalui transaksi dengan penguncian optimistis. Pengembang dapat menentukan bahwa bidang tertentu harus diperbarui secara atomik menggunakan FieldValue.serverTimestamp() dan FieldValue.arrayUnion(). Namun, Firestore tidak mendukung penggabungan tiga arah penuh — saat konflik, transaksi diulang dengan data baru, yang setara dengan percobaan ulang, bukan penggabungan nyata.
Untuk aplikasi mobile di Kotlin Multiplatform dan React Native, Merge Strategy diimplementasikan di sisi klien. Basis data lokal (SQLite, Realm) menyimpan versi setiap dokumen, dan saat sinkronisasi, klien memuat versi dari server dan melakukan penggabungan secara lokal sebelum mengirim hasilnya. Pendekatan ini memastikan pelestarian data bahkan selama pekerjaan offline yang berkepanjangan ketika lebih banyak konflik menumpuk.
Pertanyaan yang Sering Diajukan
Merge Strategy — pendekatan resolusi konflik di mana perubahan dari versi yang berbeda digabungkan menjadi satu keadaan. Berbeda dengan LWW, Merge mempertahankan perubahan dari kedua cabang jika tidak saling bertentangan di tingkat bidang.
Penggabungan tiga arah menggunakan versi dasar (keadaan sebelum divergensi) untuk menentukan bidang mana yang diubah oleh setiap klien. Penggabungan dua arah hanya membandingkan dua versi tanpa mengetahui keadaan awal, yang lebih sering menyebabkan konflik palsu.
CouchDB dan PouchDB memiliki dukungan bawaan untuk penggabungan tiga arah. Firebase Firestore memerlukan implementasi di tingkat transaksi. MongoDB dan Realm menawarkan mekanisme penguncian optimistis tetapi tidak penggabungan otomatis penuh.
Merge tidak cocok untuk data di mana kecepatan pemrosesan penting (lebih dari 1000 konflik per detik), untuk data streaming (log, peristiwa), dan untuk kasus di mana perubahan secara fundamental tidak kompatibel (versi skema data berbeda). Dalam kasus ini, LWW atau CRDT akan lebih efektif.
Implementasi mencakup tiga langkah: menyimpan versi dasar saat memuat data dari server, mendeteksi perubahan di tingkat bidang saat menyimpan, dan memanggil algoritma penggabungan saat sinkronisasi. Untuk penyederhanaan, gunakan pustaka JSON Patch atau CRDT.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga