カスタム競合解決ポリシーの作成

完了

項目間の競合を解決するために、独自のロジックを記述したい場合があります。 これは、カスタム競合解決ポリシーを使用して実現できます。

カスタム解決ポリシーでは、ストアド プロシージャを使用して、異なるリージョン内の項目間の競合を解決します。 すべてのカスタム ストアド プロシージャは、次の JavaScript 関数シグネチャを使用して実装する必要があります。

function <function-name>(incomingItem, existingItem, isTombstone, conflictingItems)

この関数では、これらの 4 つの各パラメーターが必要です。

パラメーター 説明
existingItem 既にコミットされている項目
incomingItem 競合を生成した、挿入または更新中の項目
isTombstone 受信項目が以前に削除されたかどうかを示すブール値
競合する項目 incomingItem と競合するコンテナー内のすべてのコミット済み項目の配列

/metadata/sortableTimestamp を使用して競合を解決するストアド プロシージャの実装例には、次のコードが含まれます。

function resolveConflicts(incomingItem, existingItem, isTombstone, conflictingItems) {
  if (!incomingItem) {
    if (existingItem) {
      __.deleteDocument(existingItem._self, {});
    }
  } else if (isTombstone) {
  } else {
    if (existingItem) {
      if (incomingItem.metadata.sortableTimestamp > existingItem.metadata.sortableTimestamp) {
        return;
      }
    }
    var i;
    for (i = 0; i < conflictingItems.length; i++) {
      if (incomingItem.metadata.sortableTimestamp > conflictingItems[i].metadata.sortableTimestamp) {
        return;
      }
    }
    delete (conflictingItems, incomingItem, existingItem);
  }

  function delete (documents, incoming, existing) {
    if (documents.length > 0) {
      __.deleteDocument(documents[0]._self, {}, function (err, responseOptions) {
        documents.shift();
        delete (documents, incoming, existing);
      });
    } else if (existing) {
      __.replaceDocument(existing._self, incoming);
    } else {
      __.createDocument(collection.getSelfLink(), incoming);
    }
  }
}

Azure Cosmos DB for NoSQL 用 .NET SDK を使用して、カスタム競合解決ポリシーを構成できます。 この例を開始するために、カスタム競合解決ポリシーがある products という名前のコンテナーが作成されます。

string databaseName = "cosmicworks";
string containerName = "products";
string partitionKey = "/categoryId";
string sprocName = "resolveConflicts";

Database database = client.GetDatabase(databaseName);

ContainerProperties properties = new(containerName, partitionKey)
{
    ConflictResolutionPolicy = new ConflictResolutionPolicy()
    {
        Mode = ConflictResolutionMode.Custom,
        ResolutionProcedure = $"dbs/{databaseName}/colls/{containerName}/sprocs/{sprocName}",
    }
};

Container container = database.CreateContainerIfNotExistsAsync(properties);

最後に、競合解決ポリシーをサポートするために、resolveConflicts という名前のストアド プロシージャが作成されます。

StoredProcedureProperties properties = new (sprocName, File.ReadAllText(@"code.js"))

await container.Scripts.CreateStoredProcedureAsync(properties);

また、カスタム競合解決ポリシーをストアド プロシージャなしで構成することもできます。 このシナリオでは、競合は競合フィードに書き込まれます。 その後、アプリケーション コードでフィード内の競合を手動で解決できます。

.NET を使用すると、このコード サンプルを利用して、手動で競合を解決するためのコンテナーを構成できます。

Database database = client.GetDatabase("cosmicworks");

ContainerProperties properties = new("products", "/categoryId")
{
    ConflictResolutionPolicy = new ConflictResolutionPolicy()
    {
        Mode = ConflictResolutionMode.Custom
    }
};

Container container = database.CreateContainerIfNotExistsAsync(properties);