5
votes

How can I atomically increment an integer in a document in Azure DocumentDB?

The increment operation must be atomic in the presence of concurrent writers. No lost increments are allowed (they would be possible in a naive read-modify-write algorithm).

1
What do you mean by "they would be possible in a naive read-modify-write algorithm"? Every document has an Etag and any changes sent with non-current Etag would be rejected (HTTP 412) see here - b2zw2a
Thanks. That would be answer. If you don't want to add it I'll add it myself later. - usr

1 Answers

5
votes

From the documentation:

How does DocumentDB provide concurrency?

DocumentDB supports optimistic concurrency control (OCC) through HTTP entity tags or ETags. Every DocumentDB resource has an ETag, and DocumentDB clients include their latest read version in write requests. If the ETag is current, the change is committed. If the value has been changed externally, the server rejects the write with a "HTTP 412 Precondition failure" response code. Clients must read the latest version of the resource and retry the request.

One can use this property to implement a CAS loop:

 while (true) {
  var existingDoc = ReadDoc();

  existingDoc.Int++;

  try {
   WriteDoc(existingDoc);
   break;
  }
  catch { //Concurrency violation
   continue;
  }
 }

Also note that transactions in Azure DocumentDB run on a snapshot of the data (Snapshot Isolation).

BTW: If you would like to do something a bit more automated (auto increment when someone modifies a document) you can use a trigger and separated collection for current value of an integer. Triggers are executed in the same transaction so it would be consistent and automated.