DocumentDB provides Optimistic Concurrency Control support with the ETag attribute and the AccessCondition options.
Handling these scenarios is not a cookie-cutter problem, it requires a number of moving parts and try/catch cases to nail it.
Taking a snippet of the official sample repo:
try
{
var ac = new AccessCondition { Condition = readDoc.ETag, Type = AccessConditionType.IfMatch };
readDoc.SetPropertyValue("foo", "the updated value of foo");
updatedDoc = await client.ReplaceDocumentAsync(readDoc, new RequestOptions { AccessCondition = ac });
}
catch (DocumentClientException dce)
{
// now notice the failure when attempting the update
// this is because the ETag on the server no longer matches the ETag of doc (b/c it was changed in step 2)
if (dce.StatusCode == HttpStatusCode.PreconditionFailed)
{
Console.WriteLine("As expected, we have a pre-condition failure exception\n");
}
}
These extensions are an attempt to make it less error-prone and easier to implement.
With the included extensions, the former example changes to:
updateDoc = await client.ReplaceConcurrentDocumentAsync(readDoc).OnConcurrencyException((exception)=>
{
//The original exception is in exception.InnerException
Console.WriteLine($"As expected, we have a pre-condition failure exception: {exception.Message}");
});
The key factors are the ReplaceConcurrentDocumentAsync extension and the OnConcurrencyException extension that gives you the opportunity to define a handler that will only execute on a Concurrency error.
These extensions help reduce moving parts and visually aid in understanding the program flow.
You can obtain these extensions as a Nuget Package.
Install-Package DocumentDB.Concurrency
Or reference it and use it according to the License.
Please feel free to report any issues you might encounter. I am always looking for feedback!
- .Net 4.5 Full Framework
- .Net Standard Library 1.6