Optimistic Concurrency (ETag)

From Ilianko
Revision as of 15:07, 26 October 2026 by Anko (talk | contribs) (Recreated DP-420 term page: Optimistic Concurrency (ETag) (Client Connectivity & SDK))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

← Back to DP-420 Terminology Reference

Category: Client Connectivity & SDK

Summary: Uses the ETag property with if-match preconditions to detect write conflicts.

Overview

Optimistic concurrency control in Azure Cosmos DB uses the ETag property, automatically maintained on every item, to detect conflicting concurrent updates. A client reads an item's current ETag, then includes it as an 'if-match' precondition on a subsequent update; if another process modified the item in the meantime (changing its ETag), the update fails, allowing the client to retry safely rather than silently overwrite changes.

[Image: occ_etag.jpeg (Optimistic Concurrency)]

using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
using Newtonsoft.Json;

public class Product
{
    [JsonProperty("id")]
    public string Id { get; set; }

    [JsonProperty("partitionKey")]
    public string PartitionKey { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("price")]
    public decimal Price { get; set; }

    // The _etag property is automatically managed by Azure Cosmos DB
    [JsonProperty("_etag")]
    public string ETag { get; set; }
}

public class ConcurrencyExample
{
    public async Task UpdateProductSafelyAsync(Container container, string id, string partitionKey)
    {
        try
        {
            // 1. Read the item (Client gets the document along with its current _etag)
            ItemResponse response = await container.ReadItemAsync(
                id: id, 
                partitionKey: new PartitionKey(partitionKey)
            );

            Product item = response.Resource;
            string currentETag = response.ETag; // e.g., "00000000-0000-0000-0000-000000000001"

            Console.WriteLine($"Read item with ETag: {currentETag}");

            // 2. Modify the item properties locally
            item.Price = 29.99m;

            // 3. Attempt to replace the item using Optimistic Concurrency
            // We pass the ETag we read earlier in the IfMatchEtag option.
            ItemResponse updateResponse = await container.ReplaceItemAsync(
                item: item,
                id: item.Id,
                partitionKey: new PartitionKey(item.PartitionKey),
                requestOptions: new ItemRequestOptions
                {
                    IfMatchEtag = currentETag // Cosmos DB checks if this matches the server's current ETag
                }
            );

            Console.WriteLine($"Successfully updated! New ETag: {updateResponse.ETag}");
        }
        catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.PreconditionFailed)
        {
            // 4. Handle the conflict
            Console.WriteLine("Conflict detected (412 Precondition Failed): " +
                              "Another process modified this document since it was last read. " +
                              "Please fetch the latest version and try again.");
        }
    }
}

More Info & Links

DP-420 Style Practice Questions

Q1. What Azure Cosmos DB item property is used to implement optimistic concurrency control?

  • A. ETag
  • B. Partition key
  • C. TTL
  • D. Session token

Q2. What happens when an update request includes an if-match ETag precondition that no longer matches the item's current ETag?

  • A. The update fails, signaling a conflicting concurrent modification
  • B. The update silently succeeds and overwrites the change
  • C. The item is automatically deleted
  • D. The ETag is regenerated and the update retried automatically

Answer Key

Answers are listed at the very end so you can attempt the questions first.

  • Q1 (Optimistic Concurrency (ETag)): A. ETag — The ETag property changes whenever an item is updated, and is used as an if-match precondition to detect conflicting updates.
  • Q2 (Optimistic Concurrency (ETag)): A. The update fails, signaling a conflicting concurrent modification — A mismatched ETag causes the conditional update to fail, alerting the client to a conflict rather than silently overwriting data.

DP-420: Designing and Implementing Cloud-Native Applications Using Microsoft Azure Cosmos DB — term detail page