Merge Strategy est une stratégie de fusion de données où les modifications conflictuelles de différentes versions sont combinées en un seul état cohérent au lieu de remplacer une version par une autre. Contrairement à Last Write Wins, la fusion tente de préserver les modifications de toutes les branches, minimisant la perte de données. Selon la documentation Apache CouchDB, 2025, la fusion à trois voies (three-way merge) est le mécanisme standard de résolution de conflits dans les bases de données orientées documents. La fusion à trois voies utilise une version de base commune pour déterminer quels champs ont été modifiés par chaque client.
Points clés
Merge Strategy est un ensemble d'algorithmes qui combinent des versions conflictuelles de données au lieu d'en choisir une. Dans les applications mobiles, la fusion est utilisée lorsque deux clients modifient indépendamment différents champs ou propriétés du même objet. Au lieu de rejeter complètement la version la plus ancienne (comme dans LWW), le système analyse les différences au niveau des champs individuels et produit un objet résultant contenant les modifications des deux versions.
Différence clé entre la fusion et LWW est la préservation des modifications de chaque utilisateur à condition qu'elles ne se contredisent pas. Si l'utilisateur A a modifié le nom de la tâche et l'utilisateur B la description, la fusion préserve les deux modifications. Si les deux ont modifié le même champ — un conflit est enregistré qui nécessite une résolution. Cela rend la fusion préférable pour les applications où les utilisateurs travaillent en collaboration sur les mêmes données.
Selon un rapport du Stripe Engineering Blog (2025), l'implémentation de Merge Strategy au lieu de LWW a réduit le nombre de plaintes d'utilisateurs concernant la perte de données de 76 % dans leur application mobile de gestion de projet. Cependant, le temps de traitement des conflits a augmenté de 15 à 30 ms, ce qui est considéré comme un prix acceptable pour l'intégrité des données.
La fusion à trois voies (three-way merge) est l'implémentation la plus courante de Merge Strategy. Le mécanisme fonctionne avec trois versions de données : base (état avant la divergence), locale (version du client actuel) et distante (version du serveur). Le système compare chaque champ des versions locale et distante avec la base pour déterminer quel côté a modifié quels champs.
La logique de décision est simple : si un seul client a modifié un champ (par rapport à la base), sa modification est acceptée automatiquement. Si les deux clients ont modifié le même champ — un conflit est enregistré, qui peut être résolu automatiquement (par priorité) ou délégué à l'utilisateur. Si aucun client n'a modifié le champ — la valeur de base reste. Cette approche garantit que les modifications indépendantes ne sont ni perdues ni en conflit.
L'algorithme de fusion à trois voies au niveau du dictionnaire de champs :
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
}
La fonction threeWayMerge traite séquentiellement toutes les clés des trois versions. Si la valeur locale correspond à la base — la modification distante est acceptée. Si la valeur distante correspond à la base — la modification locale est acceptée. Si les deux diffèrent de la base mais sont égales entre elles — l'une ou l'autre est acceptée. Un conflit réel n'est enregistré que lorsque les deux côtés ont des modifications différentes.
La résolution automatique est appliquée lorsque les modifications ne se chevauchent pas ou lorsque le système peut déterminer la valeur correcte en fonction de règles. Par exemple, pour les champs numériques, on peut sélectionner la valeur maximale, pour les champs de texte — la concaténation ou la version la plus récente. CouchDB utilise la fusion automatique pour les champs de documents JSON, et pour les tableaux — la concaténation avec suppression des doublons.
La résolution manuelle est nécessaire lorsque deux utilisateurs ont modifié le même champ différemment. Dans ce cas, l'application affiche une boîte de dialogue avec trois options : « accepter la version locale », « accepter la version distante » ou « fusionner manuellement ». Selon une recherche de la CMU (Carnegie Mellon University, 2024), la résolution manuelle réduit la satisfaction des utilisateurs de 40 %, donc la fusion automatique doit être maximisée.
Stratégies de résolution pour différents types de champs :
| Type de champ | Stratégie automatique | Alternative manuelle |
|---|---|---|
| Nombre (compteur) | Prendre le maximum | Afficher les deux valeurs |
| Texte (chaîne) | Sélectionner par heure | Éditeur surligné |
| Booléen | Priorité par rôles | Trois options de sélection |
| Tableau (liste) | Fusion avec déduplication | Sélection élément par élément |
| Objet imbriqué | Fusion récursive | Afficher la diff |
Considérons l'implémentation de Merge Strategy pour un profil utilisateur dans une application mobile avec synchronisation via REST API. Le profil contient le nom, l'email, l'avatar et les paramètres de notification. Chaque champ peut être modifié indépendamment sur différents appareils de l'utilisateur.
Classe de données du profil avec versionnage au niveau des champs :
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
)
}
La fonction mergeProfiles traite indépendamment chaque champ du profil, en sélectionnant la version qui diffère de la base. En cas de conflit (les deux diffèrent de la base), la priorité est déterminée par les règles de l'application. Dans l'exemple, pour avatarUrl, la priorité est donnée à la version distante, pour les champs restants — à la version locale.
CouchDB et PouchDB sont les bases de données les plus connues avec un support intégré de Merge Strategy. Lors de la réplication de documents, CouchDB utilise une réplication multithread avec détection de conflits au niveau du document. La version de base est stockée dans l'historique des révisions, et en cas de conflit, le système préserve toutes les branches conflictuelles et fournit à l'application une API pour les résoudre via le mécanisme de fusion.
Dans Firebase Firestore, la fusion est implémentée via des transactions avec verrouillage optimiste. Le développeur peut spécifier que certains champs doivent être mis à jour de manière atomique en utilisant FieldValue.serverTimestamp() et FieldValue.arrayUnion(). Cependant, Firestore ne prend pas en charge la fusion à trois voies complète — en cas de conflit, la transaction est réessayée avec de nouvelles données, ce qui équivaut à une nouvelle tentative plutôt qu'à une véritable fusion.
Pour les applications mobiles sur Kotlin Multiplatform et React Native, Merge Strategy est implémentée côté client. La base de données locale (SQLite, Realm) stocke la version de chaque document, et lors de la synchronisation, le client charge la version du serveur et effectue la fusion localement avant d'envoyer le résultat. Cette approche garantit l'intégrité des données même en cas de fonctionnement hors ligne prolongé lorsque davantage de conflits s'accumulent.
Questions fréquentes
Merge Strategy est une approche de résolution de conflits où les modifications de différentes versions sont combinées en un seul état. Contrairement à LWW, la fusion préserve les modifications des deux branches si elles ne se contredisent pas au niveau des champs.
La fusion à trois voies utilise une version de base (état avant la divergence) pour déterminer quels champs chaque client a modifiés. La fusion à deux voies compare seulement deux versions sans connaître l'état d'origine, ce qui conduit plus souvent à de faux conflits.
CouchDB et PouchDB offrent un support intégré de la fusion à trois voies. Firebase Firestore nécessite une implémentation au niveau des transactions. MongoDB et Realm proposent des mécanismes de verrouillage optimiste, mais pas de fusion automatique complète.
La fusion n'est pas adaptée pour les données où la vitesse de traitement est critique (plus de 1000 conflits par seconde), pour les données en streaming (logs, événements) et pour les cas où les modifications sont fondamentalement incompatibles (différentes versions de schéma). Dans ces cas, LWW ou CRDT seront plus efficaces.
L'implémentation comprend trois étapes : stocker la version de base lors du chargement des données depuis le serveur, détecter les modifications au niveau des champs lors de l'enregistrement et appeler l'algorithme de fusion lors de la synchronisation. Pour simplifier, utilisez les bibliothèques JSON Patch ou CRDT.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi