Home > CRM 2016 > CRM 2016 Web API – Optimistic Concurrency

CRM 2016 Web API – Optimistic Concurrency

Assume a scenario, you retrieved an Account and wanted to update the ‘Name’ field. But due to concurrency the same Account has changed on the server since you retrieved it and you may not want to complete the update.

So how to detect this situation and avoid concurrency issues? The answer is ‘Optimistic Concurrency’ patterns provided by Web API.

What’s Optimistic Concurrency

  • Optimistic concurrency can be used to detect whether an entity has been modified since it was last retrieved by using ‘ETag’ and ‘If-Match Header’.
  • Etag:
    • Each time when we retrieve an entity it will include a @odata.etag
  • eTag


    • The value of this property is updated each time the entity is updated.
    • Refer this article how to fetch Etag.
  • If-Match Header
    • If-Match header with the ETag value can be used to check whether the current value on the server matches the one found when the user last retrieved the record.

Sample Script:

Key Points to perform Optimistic Concurrency:

  • Get the @odata.etag property of record up on retrieval.
  • ‘Status’ code would be 412, if the current record is different from the server.

function updateRecord() {
var clientURL = Xrm.Page.context.getClientUrl();
var accountId = “f26b5f92-5798-e511-80e3-3863bb2ead80”;
var req = new XMLHttpRequest()
req.open(“PATCH”, encodeURI(clientURL + “/api/data/v8.0/accounts(” + accountId + “)”), true);
req.setRequestHeader(“If-Match”, “W/\”632353\””);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);

req.onreadystatechange = function () {
if (this.readyState == 4) {
req.onreadystatechange = null;
if (this.status == 204) {
var data = JSON.parse(this.response, dateReviver);
else if (this.status == 412) {
var error = JSON.parse(this.response).error;
alert(“Precondition Failed – ” + error.message);
else {
var error = JSON.parse(this.response).error;
alert(“Error updating Account – ” + error.message);

// Set Account record properties
req.send(JSON.stringify({ name: “Rajeev Pentyala” }));

function dateReviver(key, value) {
var a;
if (typeof value === ‘string’) {
a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] – 1, +a[3], +a[4], +a[5], +a[6]));
return value;

Server Response

  • Web API call fails with 412 code, if the Etag value sent with the If-Match header is different from the current value in server.
Optimistic Concurrency

Optimistic Concurrency

  • If the value had matched, a 204 status is expected.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: