Optimistic Concurrency (ETag)
← 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