Conflits

Dans les bases de données réparties, des copies de données peuvent être stockées dans plusieurs emplacements. Les caractéristiques naturelles du réseau et du système peuvent signifier que les modifications apportées à un document stocké à un emplacement ne peuvent pas être mises à jour ou répliquées instantanément dans d'autres parties de la base de données.

En d'autres termes, des mises à jour indépendantes peuvent être apportées à différentes copies de documents. Ces mises à jour peuvent avoir pour effet d'introduire des désaccords ou des "conflits" quant au contenu correct et définitif du document.

IBM® Cloudant® for IBM Cloud® tente de vous aider à éviter les conflits en vous avertissant des problèmes potentiels. Il vous avertit en renvoyant une erreur « 409 réponse » en réponse à une requête de mise à jour problématique. Toutefois, une réponse 409 risque de ne pas être reçue si la mise à jour de la base de données est demandée sur un système qui n'est pas actuellement connecté au réseau. Par exemple, la base de données peut se trouver sur un appareil mobile temporairement déconnecté d'Internet. Il est donc impossible à ce moment-là de vérifier si d'autres mises à jour potentiellement conflictuelles ont été effectuées.

Si vous demandez un document qui est en situation de conflit, IBM Cloudant renvoie le document comme prévu. Cependant, un algorithme interne tient compte d'un certain nombre de facteurs avant de déterminer la version du document à renvoyer. Vous ne devez pas partir du principe que le document renvoyé est toujours la version la plus récente.

Par exemple, si vous ne vérifiez pas les conflits ou si vous ne parvenez pas à les traiter, votre base de données IBM Cloudant peut présenter le comportement suivant :

  • Augmentation des incohérences dans le contenu des documents, car de plus en plus de documents sont en conflit.
  • Augmentation de la taille de la base de données, car tous les documents en conflit doivent être conservés jusqu'à la résolution du conflit.
  • Diminution des performances, car IBM Cloudant doit intensifier son activité en réponse à chaque demande alors qu'il tente d'identifier la "meilleure version possible" d'un document en conflit.

Les pratiques suggérées suivantes peuvent vous aider à déterminer quand rechercher et résoudre les conflits :

Pratiques suggérées
Caractéristique d'application Fréquence de la mise à jour du document Rechercher les conflits lors de l'extraction ? Rechercher les conflits lors de la mise à jour ?
Toujours connecté à Internet, par exemple un serveur. Souvent Y
Toujours connecté à Internet. Parfois
Y
Souvent connecté à Internet, mais pas toujours, par exemple un ordinateur portable. Souvent
Y
Souvent connecté à Internet, mais pas toujours. Parfois
Y
Occasionnellement connecté à Internet, par exemple une tablette. Souvent
Y

Recherche de conflits

Pour rechercher les conflits susceptibles d'affecter un document, ajoutez le paramètre de requête conflicts=true lors de l'extraction d'un document. Lorsqu'il est renvoyé, le document obtenu contient un tableau _conflicts, qui inclut une liste de toutes les révisions en conflit.

Voici un exemple de fonction de mappe pour rechercher des conflits dans des documents :

function (doc) {
  if (doc._conflicts) {
    emit(null, [doc._rev].concat(doc._conflicts));
  }
}

Pour trouver des conflits pour plusieurs documents d'une base de données, créez une vue. A l'aide d'une fonction de mappe telle que l'exemple fourni, vous pouvez rechercher toutes les révisions de chaque document comportant un conflit.

Lorsque vous disposez d'une vue de ce type, vous pouvez l'utiliser pour rechercher et résoudre les conflits si nécessaire. Vous pouvez également interroger la vue après chaque réplication pour identifier et résoudre les conflits immédiatement.

Comment résoudre des conflits

Une fois que vous avez trouvé un conflit, vous pouvez le résoudre en suivant les quatre étapes décrites ci-après.

  • Get
  • Fusionner
  • Télécharger
  • Supprimer

Voici un exemple de document de la première version :

{
  "_id": "74b2be56045bed0c8c9d24b939000dbe",
  "_rev": "1-7438df87b632b312c53a08361a7c3299",
  "name": "Samsung Galaxy S4",
  "description": "",
  "price": 650
}

Examinons un scénario pour cet exemple. Supposons que vous ayez une base de données de produits pour un magasin en ligne. La première version d'un document peut être similaire à l'exemple fourni.

Consultez la deuxième version (première révision) suivante du document dans laquelle une description est ajoutée :

{
  "_id": "74b2be56045bed0c8c9d24b939000dbe",
  "_rev": "2-61ae00e029d4f5edd2981841243ded13",
  "name": "Samsung Galaxy S4",
  "description": "Latest smartphone from Samsung",
  "price": 650
}

Le document n'a pas encore de description, donc quelqu'un pourrait en ajouter une.

Consultez la deuxième version alternative suivante qui introduit un changement de données (réduction de prix) à la première version du document :

{
  "_id": "74b2be56045bed0c8c9d24b939000dbe",
  "_rev": "2-f796915a291b37254f6df8f6f3389121",
  "name": "Samsung Galaxy S4",
  "description": "",
  "price": 600
}

Au même moment, une autre personne utilisant une base de données répliquée réduit le prix. Cette modification est apportée à la première version du document. Par conséquent, la modification de réduction de prix n'a pas "connaissance" de la modification d'ajout d'une description.

Ultérieurement, lorsque les deux bases de données sont répliquées, il peut être difficile de savoir laquelle des deux versions alternatives du document est correcte. Cet exemple est un scénario de conflit.

Obtention des révisions en conflit

Pour rechercher les révisions conflictuelles d'un document, extrayez ce document normalement, mais incluez le paramètre conflicts=true, comme dans l'exemple suivant :

https://ACCOUNT.cloudant.com/products/$_ID?conflicts=true

Voici un exemple de réponse suite à une récupération de document qui affiche des révisions en conflit :

{
  "_id":"74b2be56045bed0c8c9d24b939000dbe",
  "_rev":"2-f796915a291b37254f6df8f6f3389121",
  "name":"Samsung Galaxy S4",
  "description":"",
  "price":600,
  "_conflicts":["2-61ae00e029d4f5edd2981841243ded13"]
}

Si le document comporte des conflits, vous obtenez une réponse similaire à l'exemple fourni, qui est basé sur le problème de description modifiée ou de prix modifié.

La version avec le prix modifié a été choisie arbitrairement comme version la plus récente du document. Vous ne devez pas supposer que la version du document avec la mise à jour la plus récente soit considérée comme la dernière version à des fins de résolution de conflit.

Dans cet exemple, un conflit est considéré comme existant entre le document récupéré qui a la valeur _rev 2-f796915a291b37254f6df8f6f3389121, et un autre document qui a la valeur _rev 2-61ae00e029d4f5edd2981841243ded13. Les détails du document en conflit sont notés dans le tableau _conflicts.

Souvent, vous pouvez constater que le tableau ne contient qu'un seul élément, mais il est possible qu'il y ait de nombreuses révisions conflictuelles. Chaque révision est répertoriée dans le tableau.

Fusion des modifications

Votre application doit identifier toutes les modifications potentielles et les réconcilier, en fusionnant efficacement les mises à jour correctes et valides pour produire une version unique et non conflictuelle du document.

Pour comparer les révisions afin d'identifier les modifications, votre application doit extraire toutes les versions de la base de données. Commencez par extraire un document ainsi que les détails de toutes les versions en conflit. Pour lancer l'extraction, vous devez utiliser une commande similaire à la suivante, qui demande également le tableau _conflicts :

https://$ACCOUNT.cloudant.com/products/$_ID?conflicts=true

Cette extraction vous permet d'obtenir une version actuelle du document que vous stockez et une liste de tous les autres documents en conflit qui doivent également être extraits, par exemple ...rev=2-61ae00e029d4f5edd2981841243ded13 et ...rev=1-7438df87b632b312c53a08361a7c3299. Chacune de ces autres versions en conflit est également extraite et stockée, par exemple :

https://$ACCOUNT.cloudant.com/products/$_ID?rev=2-61ae00e029d4f5edd2981841243ded13 https://$ACCOUNT.cloudant.com/products/$_ID?rev=1-7438df87b632b312c53a08361a7c3299

Une fois que toutes les révisions en conflit d'un document sont disponibles, vous pouvez résoudre les conflits.

Dans un précédent scénario, les différences entre les versions du document concernaient différentes zones du document, ce qui facilitait leur fusion.

Des conflits plus complexes nécessiteront probablement plus d'analyses. Pour vous aider, vous pouvez choisir parmi différentes stratégies de résolution de conflit, telles que :

  • Stratégie temporelle - à l'aide d'un simple test sur la première édition ou l'édition la plus récente.
  • Evaluation de l'utilisateur - les conflits sont signalés aux utilisateurs, qui décident alors de la meilleure résolution.
  • Algorithmes de fusion sophistiqués - souvent utilisés avec les systèmes de contrôle de version. Par exemple, la fusion à trois voies.

Pour un exemple pratique du mode d'implémentation de ces modifications, consultez ce projet avec un exemple de code.

Téléchargement de la nouvelle révision

Consultez les révisions finales après avoir résolu et fusionné des modifications des précédentes révisions conflictuelles :

{
  "_id": "74b2be56045bed0c8c9d24b939000dbe",
  "_rev": "3-daaecd7213301a1ad5493186d6916755",
  "name": "Samsung Galaxy S4",
  "description": "Latest smartphone from Samsung",
  "price": 600
}

Après avoir évalué et résolu les conflits, vous créez un document intégrant les données actuelles et définitives. Ce nouveau document est téléchargé dans la base de données.

Suppression des anciennes révisions

Consultez les exemples de demande suivants relatifs à la suppression des anciennes révisions :

DELETE https://$ACCOUNT.cloudant.com/products/$_ID?rev=2-61ae00e029d4f5edd2981841243ded13
DELETE https://$ACCOUNT.cloudant.com/products/$_ID?rev=2-f796915a291b37254f6df8f6f3389121

Dans l'étape finale, vous supprimez les anciennes révisions. Pour ce faire, vous envoyez une demande DELETE, en spécifiant les révisions à supprimer.

Lorsque les anciennes versions d'un document sont supprimées, les conflits associés à ce document sont marqués comme résolus. Vous pouvez vérifier qu'aucun conflit ne subsiste en demandant à nouveau le document. Définissez le paramètre conflicts sur true et utilisez find conflicts comme auparavant.