Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dengan penulisan di banyak wilayah, saat beberapa klien melakukan penulisan pada item yang sama, konflik mungkin terjadi. Saat konflik terjadi, Anda dapat mengatasi konflik dengan menggunakan kebijakan resolusi konflik yang berbeda. Artikel ini menjelaskan cara mengelola kebijakan penyelesaian konflik.
Tip
Kebijakan resolusi konflik hanya dapat ditentukan pada waktu pembuatan kontainer dan tidak dapat dimodifikasi setelah pembuatan kontainer.
Membuat kebijakan resolusi konflik penulis-terakhir-menang
Sampel ini menunjukkan cara menyiapkan kontainer dengan kebijakan resolusi konflik "last-writer-wins" (penulis terakhir menang). Jalur default untuk last-writer-wins adalah bidang tanda waktu atau _ts properti . Untuk API untuk NoSQL, jalur ini mungkin juga diatur ke jalur yang ditentukan pengguna dengan jenis numerik. Dalam konflik, nilai tertinggi menang. Jika jalur tidak diatur atau tidak valid, jalur defaultnya adalah _ts. Konflik yang diselesaikan dengan kebijakan ini tidak muncul di umpan konflik. Semua API dapat menggunakan kebijakan ini.
.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
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();
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
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)
Go SDK (Kit Pengembangan Perangkat Lunak)
db, _ := c.NewDatabase("demo_db")
_, err = db.CreateContainer(context.Background(), azcosmos.ContainerProperties{
ID: "demo_container",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/id"},
Kind: azcosmos.PartitionKeyKindHash,
},
ConflictResolutionPolicy: &azcosmos.ConflictResolutionPolicy{
Mode: azcosmos.ConflictResolutionModeLastWriteWins,
ResolutionPath: "/myCustomId",
},
}, nil)
Membuat kebijakan resolusi konflik kustom menggunakan prosedur tersimpan
Sampel ini menunjukkan cara menyiapkan kontainer dengan kebijakan resolusi konflik kustom. Kebijakan ini menggunakan logika dalam prosedur tersimpan untuk mengatasi konflik. Jika prosedur tersimpan ditunjuk untuk mengatasi konflik, konflik tidak muncul di umpan konflik kecuali ada kesalahan dalam prosedur tersimpan yang ditunjuk.
Setelah kebijakan dibuat menggunakan kontainer, Anda perlu membuat stored procedure. Sampel SDK .NET memperlihatkan contoh alur kerja ini. Kebijakan ini hanya didukung di API untuk NoSQL.
Contoh prosedur tersimpan penyelesaian konflik kustom
Prosedur tersimpan resolusi konflik kustom harus diimplementasikan menggunakan tanda tangan fungsi yang ditunjukkan di bawah ini. Nama fungsi tidak perlu cocok dengan nama yang digunakan saat mendaftarkan prosedur tersimpan dengan kontainer, tetapi hal tersebut dapat menyederhanakan penamaan. Berikut adalah deskripsi parameter yang harus diimplementasikan untuk prosedur tersimpan ini.
- incomingItem: Item yang disisipkan atau diperbarui dalam commit yang menghasilkan konflik. Null untuk operasi penghapusan.
- existingItem: Item yang saat ini dikomitmenkan. Nilai ini tidak null dalam pembaruan, sedangkan null untuk penyisipan atau penghapusan.
- isTombstone: Boolean menunjukkan apakah incomingItem bertentangan dengan item yang dihapus sebelumnya. Ketika benar, existingItem juga null.
- conflictingItems: Array dari versi yang diterapkan dari semua item dalam kontainer yang bertentangan dengan incomingItem pada ID atau properti indeks unik lainnya.
Important
Seperti prosedur tersimpan apa pun, prosedur resolusi konflik kustom dapat mengakses data apa pun dengan kunci partisi yang sama dan dapat melakukan operasi penyisipan, pembaruan, atau penghapusan apa pun untuk mengatasi konflik.
Prosedur tersimpan sampel ini menyelesaikan konflik dengan memilih nilai terendah dari jalur /myCustomId.
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
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();
Setelah kontainer Anda dibuat, Anda harus membuat prosedur tersimpan resolver.
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`
}
}
);
Setelah kontainer Anda dibuat, Anda harus membuat prosedur tersimpan resolver.
Python SDK
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)
Setelah kontainer Anda dibuat, Anda harus membuat prosedur tersimpan resolver.
Membuat kebijakan resolusi konflik kustom
Sampel ini menunjukkan cara menyiapkan kontainer dengan kebijakan resolusi konflik kustom. Dengan implementasi ini, setiap konflik muncul di umpan konflik. Terserah Anda untuk menangani konflik satu per satu dari alur konflik.
.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
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();
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
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)
Membaca dari umpan konflik
Sampel-sampel ini menunjukkan cara membaca dari umpan konflik dari kontainer. Konflik mungkin muncul di umpan konflik hanya karena beberapa alasan:
- Konflik tidak diselesaikan secara otomatis
- Konflik menyebabkan kesalahan dengan prosedur tersimpan yang ditentukan
- Kebijakan resolusi konflik diatur ke kustom dan tidak menunjuk prosedur tersimpan untuk menangani konflik
.NET SDK
FeedResponse<Conflict> conflicts = await delClient.ReadConflictFeedAsync(this.collectionUri);
Java SDK
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)
Langkah berikutnya
Pelajari tentang konsep Azure Cosmos DB berikut ini:
- Distribusi global - di balik layar
- Cara mengonfigurasi penulisan multiwilayah di aplikasi Anda
- Mengonfigurasi klien untuk multihoming
- Tambahkan atau hapus wilayah dari akun Azure Cosmos DB Anda
- Cara mengonfigurasi penulisan multi-wilayah di aplikasi Anda.
- Pemartisian dan distribusi data
- Pengindeksan di Azure Cosmos DB