Školení
Modul
Konfigurace zápisu do více oblastí ve službě Azure Cosmos DB for NoSQL - Training
Zápis dat do více oblastí pomocí služby Azure Cosmos DB for NoSQL
Tento prohlížeč se už nepodporuje.
Upgradujte na Microsoft Edge, abyste mohli využívat nejnovější funkce, aktualizace zabezpečení a technickou podporu.
PLATÍ PRO: NoSQL
Při zápisech do více oblastí může dojít ke konfliktům při zápisu více klientů do stejné položky. Pokud dojde ke konfliktu, můžete konflikt vyřešit pomocí různých zásad řešení konfliktů. Tento článek popisuje, jak spravovat zásady řešení konfliktů.
Tip
Zásady řešení konfliktů je možné zadat pouze při vytváření kontejneru a po vytvoření kontejneru je nelze upravit.
Tyto ukázky ukazují, jak nastavit kontejner se zásadami řešení konfliktů posledního zapisovače. Výchozí cesta pro poslední zapisovač-wins je pole časového razítka _ts
nebo vlastnost. Pro rozhraní API pro NoSQL to může být také nastaveno na uživatelsky definovanou cestu s číselným typem. V konfliktu vyhraje nejvyšší hodnota. Pokud cesta není nastavená nebo je neplatná, výchozí hodnota je _ts
. Konflikty vyřešené touto zásadou se v informačním kanálu konfliktů nezobrazují. Tuto zásadu můžou používat všechna rozhraní API.
DocumentCollection lwwCollection = await createClient.CreateDocumentCollectionIfNotExistsAsync(
UriFactory.CreateDatabaseUri(this.databaseName), new DocumentCollection
{
Id = this.lwwCollectionName,
ConflictResolutionPolicy = new ConflictResolutionPolicy
{
Mode = ConflictResolutionMode.LastWriterWins,
ConflictResolutionPath = "/myCustomId",
},
});
Rozhraní Async API sady Java SDK V4 (Maven com::azure-cosmos)
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createLastWriterWinsPolicy("/myCustomId");
CosmosContainerProperties containerProperties = new CosmosContainerProperties(container_id, partition_key);
containerProperties.setConflictResolutionPolicy(policy);
/* ...other container config... */
database.createContainerIfNotExists(containerProperties).block();
Async Java V2 SDK (Maven com.microsoft.azure::azure-cosmosdb)
DocumentCollection collection = new DocumentCollection();
collection.setId(id);
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createLastWriterWinsPolicy("/myCustomId");
collection.setConflictResolutionPolicy(policy);
DocumentCollection createdCollection = client.createCollection(databaseUri, collection, null).toBlocking().value();
const database = client.database(this.databaseName);
const { container: lwwContainer } = await database.containers.createIfNotExists(
{
id: this.lwwContainerName,
conflictResolutionPolicy: {
mode: "LastWriterWins",
conflictResolutionPath: "/myCustomId"
}
}
);
database = client.get_database_client(database=database_id)
lww_conflict_resolution_policy = {'mode': 'LastWriterWins', 'conflictResolutionPath': '/regionId'}
lww_container = database.create_container(id=lww_container_id, partition_key=PartitionKey(path="/id"),
conflict_resolution_policy=lww_conflict_resolution_policy)
Tyto ukázky předvádějí, jak nastavit kontejner s vlastní zásadou řešení konfliktů. Tato zásada používá logiku uložené procedury k vyřešení konfliktu. Pokud je uložená procedura určená k vyřešení konfliktů, konflikty se v informačním kanálu konfliktů nezobrazí, pokud v určené uložené proceduře nedojde k chybě.
Po vytvoření zásady s kontejnerem je potřeba vytvořit uloženou proceduru. Následující ukázka sady .NET SDK ukazuje příklad tohoto pracovního postupu. Tyto zásady se podporují jenom v rozhraní API pro NoSQL.
Uložené procedury vlastního řešení konfliktů musí být implementovány pomocí podpisu funkce uvedeného níže. Název funkce se nemusí shodovat s názvem použitým při registraci uložené procedury v kontejneru, ale zjednodušuje pojmenování. Tady je popis parametrů, které musí být implementovány pro tuto uloženou proceduru.
Důležité
Stejně jako u všech uložených procedur má vlastní procedura řešení konfliktů přístup k jakýmkoli datům se stejným klíčem oddílu a může provádět jakoukoli operaci vložení, aktualizace nebo odstranění za účelem vyřešení konfliktů.
Tato ukázková uložená procedura vyřeší konflikty výběrem nejnižší hodnoty z /myCustomId
cesty.
function resolver(incomingItem, existingItem, isTombstone, conflictingItems) {
var collection = getContext().getCollection();
if (!incomingItem) {
if (existingItem) {
collection.deleteDocument(existingItem._self, {}, function (err, responseOptions) {
if (err) throw err;
});
}
} else if (isTombstone) {
// delete always wins.
} else {
if (existingItem) {
if (incomingItem.myCustomId > existingItem.myCustomId) {
return; // existing item wins
}
}
var i;
for (i = 0; i < conflictingItems.length; i++) {
if (incomingItem.myCustomId > conflictingItems[i].myCustomId) {
return; // existing conflict item wins
}
}
// incoming item wins - clear conflicts and replace existing with incoming.
tryDelete(conflictingItems, incomingItem, existingItem);
}
function tryDelete(documents, incoming, existing) {
if (documents.length > 0) {
collection.deleteDocument(documents[0]._self, {}, function (err, responseOptions) {
if (err) throw err;
documents.shift();
tryDelete(documents, incoming, existing);
});
} else if (existing) {
collection.replaceDocument(existing._self, incoming,
function (err, documentCreated) {
if (err) throw err;
});
} else {
collection.createDocument(collection.getSelfLink(), incoming,
function (err, documentCreated) {
if (err) throw err;
});
}
}
}
DocumentCollection udpCollection = await createClient.CreateDocumentCollectionIfNotExistsAsync(
UriFactory.CreateDatabaseUri(this.databaseName), new DocumentCollection
{
Id = this.udpCollectionName,
ConflictResolutionPolicy = new ConflictResolutionPolicy
{
Mode = ConflictResolutionMode.Custom,
ConflictResolutionProcedure = string.Format("dbs/{0}/colls/{1}/sprocs/{2}", this.databaseName, this.udpCollectionName, "resolver"),
},
});
//Create the stored procedure
await clients[0].CreateStoredProcedureAsync(
UriFactory.CreateStoredProcedureUri(this.databaseName, this.udpCollectionName, "resolver"), new StoredProcedure
{
Id = "resolver",
Body = File.ReadAllText(@"resolver.js")
});
Rozhraní Async API sady Java SDK V4 (Maven com::azure-cosmos)
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createCustomPolicy("resolver");
CosmosContainerProperties containerProperties = new CosmosContainerProperties(container_id, partition_key);
containerProperties.setConflictResolutionPolicy(policy);
/* ...other container config... */
database.createContainerIfNotExists(containerProperties).block();
Async Java V2 SDK (Maven com.microsoft.azure::azure-cosmosdb)
DocumentCollection collection = new DocumentCollection();
collection.setId(id);
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createCustomPolicy("resolver");
collection.setConflictResolutionPolicy(policy);
DocumentCollection createdCollection = client.createCollection(databaseUri, collection, null).toBlocking().value();
Po vytvoření kontejneru je nutné vytvořit uloženou proceduru resolver
.
const database = client.database(this.databaseName);
const { container: udpContainer } = await database.containers.createIfNotExists(
{
id: this.udpContainerName,
conflictResolutionPolicy: {
mode: "Custom",
conflictResolutionProcedure: `dbs/${this.databaseName}/colls/${
this.udpContainerName
}/sprocs/resolver`
}
}
);
Po vytvoření kontejneru je nutné vytvořit uloženou proceduru resolver
.
database = client.get_database_client(database=database_id)
udp_custom_resolution_policy = {'mode': 'Custom' }
udp_container = database.create_container(id=udp_container_id, partition_key=PartitionKey(path="/id"),
conflict_resolution_policy=udp_custom_resolution_policy)
Po vytvoření kontejneru je nutné vytvořit uloženou proceduru resolver
.
Tyto ukázky předvádějí, jak nastavit kontejner s vlastní zásadou řešení konfliktů. Při této implementaci se každý konflikt zobrazí v informačním kanálu konfliktů. Je na vás, abyste konflikty zvládli jednotlivě z informačního kanálu konfliktů.
DocumentCollection manualCollection = await createClient.CreateDocumentCollectionIfNotExistsAsync(
UriFactory.CreateDatabaseUri(this.databaseName), new DocumentCollection
{
Id = this.manualCollectionName,
ConflictResolutionPolicy = new ConflictResolutionPolicy
{
Mode = ConflictResolutionMode.Custom,
},
});
Rozhraní Async API sady Java SDK V4 (Maven com::azure-cosmos)
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createCustomPolicy();
CosmosContainerProperties containerProperties = new CosmosContainerProperties(container_id, partition_key);
containerProperties.setConflictResolutionPolicy(policy);
/* ...other container config... */
database.createContainerIfNotExists(containerProperties).block();
Async Java V2 SDK (Maven com.microsoft.azure::azure-cosmosdb)
DocumentCollection collection = new DocumentCollection();
collection.setId(id);
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createCustomPolicy();
collection.setConflictResolutionPolicy(policy);
DocumentCollection createdCollection = client.createCollection(databaseUri, collection, null).toBlocking().value();
const database = client.database(this.databaseName);
const {
container: manualContainer
} = await database.containers.createIfNotExists({
id: this.manualContainerName,
conflictResolutionPolicy: {
mode: "Custom"
}
});
database = client.get_database_client(database=database_id)
manual_resolution_policy = {'mode': 'Custom'}
manual_container = database.create_container(id=manual_container_id, partition_key=PartitionKey(path="/id"),
conflict_resolution_policy=manual_resolution_policy)
Tyto ukázky předvádějí, jak číst z informačního kanálu konfliktů kontejneru. Konflikty se můžou v informačním kanálu konfliktů zobrazovat jenom z několika důvodů:
FeedResponse<Conflict> conflicts = await delClient.ReadConflictFeedAsync(this.collectionUri);
Java V4 SDK (Maven com.azure::azure-cosmos)
int requestPageSize = 3;
CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
CosmosPagedFlux<CosmosConflictProperties> conflictReadFeedFlux = container.readAllConflicts(options);
conflictReadFeedFlux.byPage(requestPageSize).toIterable().forEach(page -> {
int expectedNumberOfConflicts = 0;
int numberOfResults = 0;
Iterator<CosmosConflictProperties> pageIt = page.getElements().iterator();
while (pageIt.hasNext()) {
CosmosConflictProperties conflictProperties = pageIt.next();
// Read the conflict and committed item
CosmosAsyncConflict conflict = container.getConflict(conflictProperties.getId());
CosmosConflictResponse response = conflict.read(new CosmosConflictRequestOptions()).block();
// response.
}
});
const container = client
.database(this.databaseName)
.container(this.lwwContainerName);
const { result: conflicts } = await container.conflicts.readAll().toArray();
conflicts_iterator = iter(container.list_conflicts())
conflict = next(conflicts_iterator, None)
while conflict:
# Do something with conflict
conflict = next(conflicts_iterator, None)
Seznamte se s následujícími koncepty služby Azure Cosmos DB:
Školení
Modul
Konfigurace zápisu do více oblastí ve službě Azure Cosmos DB for NoSQL - Training
Zápis dat do více oblastí pomocí služby Azure Cosmos DB for NoSQL
Dokumentace
Konfigurace globální distribuce služby Azure Cosmos DB - Azure Cosmos DB for NoSQL
Zjistěte, jak nastavit globální distribuci služby Azure Cosmos DB pomocí rozhraní API pro NoSQL s .NET, Javou, Pythonem a různými dalšími sadami SDK.
Principy zápisů do více oblastí ve službě Azure Cosmos DB
Tento článek popisuje, jak ve službě Azure Cosmos DB fungují zápisy do více oblastí.
Typy řešení konfliktů a zásady řešení konfliktů ve službě Azure Cosmos DB
Tento článek popisuje konfliktní kategorie a zásady řešení konfliktů ve službě Azure Cosmos DB.