Gabriel Boya
Gabriel Boya

Reputation: 771

Conflict errors (409) when creating documents with Automatic ID generation on Lazy-indexed collection

I use DocumentDB with the .NET SDK on a collection for which I set a custom indexing policy using IndexingMode.Lazy. This provides me eventual consistency for all operations on the collection.

I want to do upsert-like operation on non-critical data : I can afford duplicates and missed updates.

I use code like this :

public async Task UpsertChunk(MyChunk chunk)
{
    var id = _documentClient
                    .CreateDocumentQuery<PersistentChunk>()
                    .Where(c => c.ChunkKey == chunk.ChunkKey)
                    .Select(c => c.id)
                    .FirstOrDefault();

    var persistentChunk = chunk.ToPersistentChunk();
    if (string.IsNullOrEmpty(id))
    {
        await _documentClient.CreateDocumentAsync(_collectionUri, persistentChunk);
    }
    else
    {
        persistentChunk.id = id;
        var uri = UriFactory.CreateDocumentUri(_databaseId, _collectionId, id);
        await _documentClient.ReplaceDocumentAsync(uri, persistentChunk);
    }
}

I get, non-consistently, Conflict errors : Microsoft.Azure.Documents.DocumentClientException: Message: {"Errors":["Resource with specified id or name already exists"]}

However, since I use Automatic ID Generation, it should not be possible to have duplicate ids, even in the case of concurrent writes.

Has anyone encountered this kind of behavior before ? I suspect this could be triggered by retries executed by the .NET SDK if successful writes are not acknowledged as such by DocumentDB.

Upvotes: 5

Views: 9712

Answers (1)

Fei Han
Fei Han

Reputation: 27815

Conflict errors : Microsoft.Azure.Documents.DocumentClientException: Message: {"Errors":["Resource with specified id or name already exists"]}

409 Conflict indicates the id provided for a resource on a PUT or POST operation has been taken by an existing resource. Please try to query documents by id property instead of ChunkKey property, and then you could determine to add/replace document based on the query result num.

var num = client.CreateDocumentQuery<MyChunk>("dbs/{your db}/colls/{your collection}").Where(c => c.id == chunk.id).AsEnumerable().Count();

Upvotes: 0

Related Questions