Azure Cosmos DB'de çakışma çözümleme ilkelerini yönetme
UYGULANANLAR: NoSQL
Çok bölgeli yazmalarda, aynı öğeye birden çok istemci yazdığında çakışmalar oluşabilir. Çakışma oluştuğunda, farklı çakışma çözümleme ilkeleri kullanarak çakışmayı çözebilirsiniz. Bu makalede, çakışma çözümleme ilkelerinin nasıl yönetileceğini açıklanmaktadır.
İpucu
Çakışma çözümleme ilkesi yalnızca kapsayıcı oluşturma zamanında belirtilebilir ve kapsayıcı oluşturulduktan sonra değiştirilemez.
Son yazıcı-wins çakışma çözümleme ilkesi oluşturma
Bu örnekler, son yazıcı-wins çakışma çözümleme ilkesiyle bir kapsayıcının nasıl ayarlandığını gösterir. Son yazan-kazançlar için varsayılan yol zaman damgası alanı veya özelliğidir _ts
. NoSQL API'sinde bu, sayısal türe sahip kullanıcı tanımlı bir yola da ayarlanabilir. Bir çakışmada en yüksek değer kazanır. Yol ayarlanmadıysa veya geçersizse, varsayılan olarak olur _ts
. Bu ilkeyle çözülen çakışmalar çakışma akışında gösterilmez. Bu ilke tüm API'ler tarafından kullanılabilir.
.NET SDK
DocumentCollection lwwCollection = await createClient.CreateDocumentCollectionIfNotExistsAsync(
UriFactory.CreateDatabaseUri(this.databaseName), new DocumentCollection
{
Id = this.lwwCollectionName,
ConflictResolutionPolicy = new ConflictResolutionPolicy
{
Mode = ConflictResolutionMode.LastWriterWins,
ConflictResolutionPath = "/myCustomId",
},
});
Java V4 SDK
Java SDK V4 (Maven com.azure::azure-cosmos) Async API
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createLastWriterWinsPolicy("/myCustomId");
CosmosContainerProperties containerProperties = new CosmosContainerProperties(container_id, partition_key);
containerProperties.setConflictResolutionPolicy(policy);
/* ...other container config... */
database.createContainerIfNotExists(containerProperties).block();
Java V2 SDK'ları
Zaman uyumsuz Java V2 SDK'sı (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();
Node.js/JavaScript/TypeScript SDK
const database = client.database(this.databaseName);
const { container: lwwContainer } = await database.containers.createIfNotExists(
{
id: this.lwwContainerName,
conflictResolutionPolicy: {
mode: "LastWriterWins",
conflictResolutionPath: "/myCustomId"
}
}
);
Python SDK'sı
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)
Saklı yordam kullanarak özel çakışma çözümleme ilkesi oluşturma
Bu örnekler özel çakışma çözümleme ilkesine sahip bir kapsayıcı ayarlama adımlarını göstermektedir. Bu ilke, çakışmayı çözmek için saklı yordamdaki mantığı kullanır. Bir saklı yordam çakışmaları çözmek için belirlenmişse, belirtilen saklı yordamda bir hata olmadığı sürece çakışmalar çakışma akışında gösterilmez.
kapsayıcısıyla ilke oluşturulduktan sonra saklı yordamı oluşturmanız gerekir. Aşağıdaki .NET SDK örneği, bu iş akışının bir örneğini gösterir. Bu ilke yalnızca NoSQL için API'de desteklenir.
Örnek özel çakışma çözümleme saklı yordamı
Özel çakışma çözümleme saklı yordamları aşağıda gösterilen işlev imzası kullanılarak uygulanmalıdır. İşlev adının, saklı yordamı kapsayıcıya kaydederken kullanılan adla eşleşmesi gerekmez, ancak adlandırmayı basitleştirir. Bu saklı yordam için uygulanması gereken parametrelerin açıklaması aşağıdadır.
- incomingItem: Çakışmaları oluşturan işlemeye eklenen veya güncelleştirilen öğe. Silme işlemleri için null değeridir.
- existingItem: İşlenmekte olan öğe. Bu değer bir güncelleştirmede null değil ve ekleme veya silme işlemleri için null.
- isTombstone: IncomingItem öğesinin daha önce silinmiş bir öğeyle çakışıp çakışmadığını gösteren Boole değeri. True olduğunda, existingItem da null değeridir.
- conflictingItems: Kapsayıcıdaki id veya diğer benzersiz dizin özelliklerindeki incomingItem ile çakışan tüm öğelerin kaydedilmiş sürümünün dizisi.
Önemli
Herhangi bir saklı yordamda olduğu gibi, özel çakışma çözümleme yordamı da aynı bölüm anahtarına sahip tüm verilere erişebilir ve çakışmaları çözmek için herhangi bir ekleme, güncelleştirme veya silme işlemi gerçekleştirebilir.
Bu örnek saklı yordam, yoldaki /myCustomId
en düşük değeri seçerek çakışmaları çözer.
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;
});
}
}
}
.NET SDK
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")
});
Java V4 SDK
Java SDK V4 (Maven com.azure::azure-cosmos) Async API
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createCustomPolicy("resolver");
CosmosContainerProperties containerProperties = new CosmosContainerProperties(container_id, partition_key);
containerProperties.setConflictResolutionPolicy(policy);
/* ...other container config... */
database.createContainerIfNotExists(containerProperties).block();
Java V2 SDK'ları
Zaman uyumsuz Java V2 SDK'sı (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();
Kapsayıcınız oluşturulduktan sonra saklı yordamı oluşturmanız resolver
gerekir.
Node.js/JavaScript/TypeScript SDK
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`
}
}
);
Kapsayıcınız oluşturulduktan sonra saklı yordamı oluşturmanız resolver
gerekir.
Python SDK'sı
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)
Kapsayıcınız oluşturulduktan sonra saklı yordamı oluşturmanız resolver
gerekir.
Özel bir çakışma çözümleme ilkesi oluşturma
Bu örnekler özel çakışma çözümleme ilkesine sahip bir kapsayıcı ayarlama adımlarını göstermektedir. Bu uygulamayla, her çakışma çakışma akışında gösterilir. Çakışmaları çakışma akışından ayrı ayrı işlemek size bağlı.
.NET SDK
DocumentCollection manualCollection = await createClient.CreateDocumentCollectionIfNotExistsAsync(
UriFactory.CreateDatabaseUri(this.databaseName), new DocumentCollection
{
Id = this.manualCollectionName,
ConflictResolutionPolicy = new ConflictResolutionPolicy
{
Mode = ConflictResolutionMode.Custom,
},
});
Java V4 SDK
Java SDK V4 (Maven com.azure::azure-cosmos) Async API
ConflictResolutionPolicy policy = ConflictResolutionPolicy.createCustomPolicy();
CosmosContainerProperties containerProperties = new CosmosContainerProperties(container_id, partition_key);
containerProperties.setConflictResolutionPolicy(policy);
/* ...other container config... */
database.createContainerIfNotExists(containerProperties).block();
Java V2 SDK'ları
Zaman uyumsuz Java V2 SDK'sı (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();
Node.js/JavaScript/TypeScript SDK
const database = client.database(this.databaseName);
const {
container: manualContainer
} = await database.containers.createIfNotExists({
id: this.manualContainerName,
conflictResolutionPolicy: {
mode: "Custom"
}
});
Python SDK'sı
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)
Çakışma akışından okuma
Bu örnekler, kapsayıcının çakışma akışından okuma yöntemlerini göstermektedir. Çakışmalar çakışma akışında yalnızca birkaç nedenden dolayı görünebilir:
- Çakışma otomatik olarak çözümlenmedi
- Çakışma, belirtilen saklı yordamda hataya neden oldu
- Çakışma çözümleme ilkesi özel olarak ayarlanır ve çakışmaları işlemek için saklı yordam belirlemez
.NET SDK
FeedResponse<Conflict> conflicts = await delClient.ReadConflictFeedAsync(this.collectionUri);
Java SDK’ları
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.
}
});
Node.js/JavaScript/TypeScript SDK
const container = client
.database(this.databaseName)
.container(this.lwwContainerName);
const { result: conflicts } = await container.conflicts.readAll().toArray();
Python
conflicts_iterator = iter(container.list_conflicts())
conflict = next(conflicts_iterator, None)
while conflict:
# Do something with conflict
conflict = next(conflicts_iterator, None)
Sonraki adımlar
Aşağıdaki Azure Cosmos DB kavramları hakkında bilgi edinin:
- Küresel dağıtım - arka planda
- Uygulamalarınızda çok bölgeli yazmaları yapılandırma
- İstemcileri birden çok ana bağlantı için yapılandırma
- Azure Cosmos DB hesabınızda bölge ekleme veya kaldırma
- Uygulamalarınızdamulti-region yazmalarını yapılandırma.
- Bölümleme ve veri dağıtımı
- Azure Cosmos DB’de dizin oluşturma