カスタム競合解決ポリシーの作成
項目間の競合を解決するために、独自のロジックを記述したい場合があります。 これは、カスタム競合解決ポリシーを使用して実現できます。
カスタム解決ポリシーでは、ストアド プロシージャを使用して、異なるリージョン内の項目間の競合を解決します。 すべてのカスタム ストアド プロシージャは、次の 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);