IBM Cloud Docs
Konflikte

Konflikte

In verteilten Datenbanken werden Kopien von Daten möglicherweise an mehr als einer Position gespeichert. Die wirklichkeitsgetreuen Kenndaten des Netzes und/oder Systems können dafür sorgen, dass Dokumentänderungen an einer Position nicht sofort in andere Teile der Datenbank übernommen oder repliziert werden können.

Mit anderen Worten: Unabhängige Aktualisierungen für verschiedene Kopien von Dokumenten können durchgeführt werden. Dies kann zu abweichenden Einschätzungen (Konflikten) führen, welche Kopie den aktuellen und gültigen Inhalt des Dokuments enthält.

IBM® Cloudant® for IBM Cloud® unterstützt die Vermeidung von Konflikten durch Warnungen vor potenziellen Problemen. Es warnt Sie, indem es eine 409 Antwort auf eine problematische Aktualisierungsanfrage zurückgibt. Eine solche Antwort 409 wird jedoch möglicherweise nicht empfangen, wenn die Datenbankaktualisierung in einem System angefordert wird, das gegenwärtig nicht mit dem Netz verbunden ist. Wenn sich die Datenbank beispielsweise auf einem mobilen Gerät befindet, das vorübergehend vom Internet getrennt ist, kann in diesem Zeitraum nicht geprüft werden, ob weitere Aktualisierungen vorgenommen wurden, die zu Konflikten führen können.

Wenn Sie ein Dokument anfordern, das sich in einer Konfliktsituation befindet, gibt IBM Cloudant das Dokument wie erwartet zurück. Von einem internen Algorithmus wird jedoch eine Reihe von Faktoren berücksichtigt, bevor ermittelt wird, welche Dokumentversion zurückgegeben werden soll. Sie dürfen nicht davon ausgehen, dass es sich bei dem zurückgegebenen Dokument um die aktuellste Version handelt.

Wenn Sie zum Beispiel keine Konfliktprüfung durchführen oder diese nicht beseitigen, weist die IBM Cloudant-Datenbank möglicherweise die folgenden Verhaltensweisen auf:

  • Immer mehr Inkonsistenzen im Dokumentinhalt durch die Zunahme von Dokumentkonflikten
  • Zunahme der Datenbankgröße, da alle betroffenen Dokumente aufbewahrt werden müssen, bis die Konflikte behoben sind
  • Geringere Leistung durch den erhöhten Verarbeitungsaufwand für Anforderungen in IBM Cloudant, um bei Konflikten die "optimale" Dokumentversion zu ermitteln

Die folgenden empfohlenen Vorgehensweisen können dabei helfen, den geeigneten Zeitpunkt für die Erkennung und Behebung von Konflikte zu identifizieren:

Empfohlene Praktiken
Anwendungsmerkmal Häufigkeit der Dokumentaktualisierung Konfliktprüfung beim Abrufen? Konfliktprüfung beim Aktualisieren?
Ständige Verbindung zum Netz (z. B. bei einem Server). Häufig Y
Ständige Verbindung zum Netz. Gelegentlich
Y
Häufige, jedoch nicht ständige Verbindung zum Netz (z. B. bei einem Laptop). Häufig
Y
Häufige, jedoch nicht ständige Verbindung zum Netz. Gelegentlich
Y
Gelegentliche Verbindung zum Netz (z. B. bei einem Tablet-Computer). Häufig
Y

Konflikte erkennen

Um Konflikte zu erkennen, die sich auf ein Dokument auswirken können, fügen Sie beim Abrufen eines Dokuments den Abfrageparameter conflicts=true hinzu. Das resultierende Dokument enthält das Array _conflicts mit einer Liste aller Revisionen, für die Konflikte bestehen.

Beispiel einer 'map'-Funktion zum Erkennen von Dokumentkonflikten:

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

Schreiben Sie eine Ansicht, um Konflikte für mehrere Dokumente in einer Datenbank zu finden. Mithilfe einer 'map'-Funktion wie im vorliegenden Beispiel können Sie alle Revisionen für jedes Dokument finden, für die ein Konflikt besteht.

Wenn eine solche Ansicht verfügbar ist, kann sie verwendet werden, um Konflikte bei Bedarf zu finden und zu lösen. Alternativ können Sie die Ansicht nach jeder Replikation abfragen, um Konflikte sofort zu erkennen und zu Lösen.

Vorgehensweise beim Lösen von Konflikten

Nachdem Sie einen Konflikt gefunden haben, können Sie ihn in vier Schritten beheben, die nachfolgend aufgeführt sind.

  • Abrufen
  • Zusammenführen
  • Hochladen
  • Löschen

Beispieldokument der ersten Version:

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

Nachfolgend finden Sie ein Szenario für dieses Beispiel. Angenommen, Sie haben eine Datenbank mit Produkten für einen Onlineshop. Die erste Version eines Dokuments kann dem angegebenen Beispiel ähneln:

Zweite Version (erste Revision) des Dokuments mit hinzugefügter Beschreibung:

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

Da das Dokument noch nicht über eine Beschreibung verfügt, kann ein Benutzer eine Beschreibung hinzufügen.

Alternative zweite Version, in der eine Änderung der Preissenkungsdaten gegenüber der ersten Dokumentversion eingeführt wird:

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

Zur gleichen Zeit setzt ein anderer Benutzer, der mit einer replizierten Datenbank arbeitet, den Preis herab. Diese Änderung wird in der ersten Dokumentversion vorgenommen. Die Preissenkungsänderung "kennt" daher nicht die geänderte Beschreibung.

Beim späteren Replizieren der beiden Datenbanken ist möglicherweise nicht eindeutig klar, welche der beiden verschiedenen Dokumentversionen korrekt ist. Dieses Beispiel ist ein Konfliktszenario.

Konfliktrevisionen abrufen

Um alle Konfliktrevisionen für ein Dokument zu finden, rufen Sie das Dokument wie gewohnt ab und fügen Sie dabei den Parameter conflicts=true ein, wie im folgenden Beispiel gezeigt:

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

Beispielantwort auf den Dokumentenabruf, die in Konflikt stehende Revisionen zeigt:

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

Wenn für das Dokument Konflikte bestehen, erhalten Sie eine Antwort ähnlich wie im vorliegenden Beispiel, die auf der geänderten Beschreibung oder der Preisänderung basiert.

Die Version mit dem geänderten Preis wurde beliebig als aktuelle Version des Dokuments ausgewählt. Sie dürfen nicht davon ausgehen, dass die zuletzt aktualisierte Dokumentversion als neueste Version für die Konfliktlösung eingestuft wird.

Im vorliegenden Beispiel wird von einem Konflikt zwischen dem abgerufenen Dokument mit dem _rev-Wert 2-f796915a291b37254f6df8f6f3389121 und einem anderen Dokument mit dem _rev-Wert 2-61ae00e029d4f5edd2981841243ded13 ausgegangen. Die Details für das Dokument mit bestehendem Konflikt sind im Array _conflicts aufgeführt.

Obwohl das Array häufig nur ein einziges Element enthält, können mehrere Konfliktrevisionen vorhanden sein. Jede Revision wird im Array aufgelistet.

Änderungen zusammenführen

Ihre Anwendung muss alle potenziellen Änderungen identifizieren und abgleichen, indem die korrekten und gültigen Aktualisierungen zu einer einzigen, konfliktfreien Dokumentversion zusammengeführt werden.

Um mithilfe eines Vergleichs der Revisionen zu ermitteln, was geändert wurde, muss Ihre Anwendung alle Versionen aus der Datenbank abrufen. Zunächst rufen Sie ein Dokument und die Details aller in Konflikt stehenden Versionen ab. Um den Abruf zu starten, verwenden Sie einen Befehl ähnlich dem folgenden, von dem auch das Array _conflicts angefordert wird:

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

Diese Abfrage liefert eine aktuelle Version des Dokuments, die gespeichert wird, und eine Liste aller weiteren, in Konflikt stehenden Dokumente, die ebenfalls abgerufen werden müssen, zum Beispiel ...rev=2-61ae00e029d4f5edd2981841243ded13 und ...rev=1-7438df87b632b312c53a08361a7c3299. Jede dieser weiteren, in Konflikt stehenden Versionen wird ebenfalls abgerufen und gespeichert, wie im folgenden Beispiel gezeigt:

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

Sobald alle in Konflikt stehenden Versionen eines Dokuments zur Verfügung stehen, können die Konflikte gelöst werden.

In dem zuvor verwendeten Szenario bestanden Unterschiede zwischen den Dokumentversionen in verschiedenen Feldern des Dokuments, die ohne großen Aufwand zusammengeführt werden konnten.

Komplexere Konflikte erfordern wahrscheinlich einen größeren Analyseaufwand. Als Hilfsmittel können Sie auf verschiedene Konfliktlösungsstrategien wie die folgenden zurückgreifen:

  • Zeitbasiert - Ein einfacher Test, um die zuerst oder zuletzt ausgeführte Bearbeitung zu ermitteln.
  • Benutzerbewertung - Die Konflikte werden den Benutzern gemeldet, damit sie über die beste Lösung entscheiden.
  • Hoch entwickelte Zusammenführungsalgorithmen - Diese werden häufig mit Systemen zur Versionssteuerung verwendet. Ein Beispiel hierfür ist die 3-Wege-Zusammenführung (3-way merge).

Ein praktisches Beispiel für die Implementierung dieser Änderungen finden Sie in diesem Projekt mit Beispielcode.

Neue Revision hochladen

Finale Revisionen nach dem Auflösen und Zusammenführen der Änderungen aus den vorherigen, in Konflikt stehenden Revisionen:

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

Nach dem Bewerten und Auflösen der Konflikte erstellen Sie ein Dokument, das die aktuellen und verbindlichen Daten enthält. Dieses aktuelle Dokument wird in die Datenbank hochgeladen.

Alte Revisionen löschen

Beispielanforderungen zum Löschen der alten Revisionen:

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

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

Im letzten Schritt löschen Sie die alten Revisionen. Zu diesem Zweck setzen Sie eine Anforderung DELETE ab, in der die zu löschenden Revisionen angegeben sind.

Nach dem Löschen der älteren Versionen eines Dokuments werden die zugehörigen Konflikte für das Dokument als gelöst (behoben) markiert. Sie können sicherstellen, dass keine Konflikte bestehen bleiben, indem Sie das Dokument erneut anfordern. Setzen Sie den Parameter conflicts auf 'true' und verwenden Sie den Ansatz zum Finden von Konflikten wie zuvor.