On traditional relational databases, in order to prevent a Last Writer wins scenario, updates are usually done like:
update MyTable
set myColumn = @newValue,
version=version 1
where myPk = @pk and version = @versionObtainedPreviously
how can I implement a similar behavior using Azure Table Storage?
CodePudding user response:
Optimistic concurrency in Azure Table Storage is handled through ETag
property on the entity. Anytime an entity is updated, its ETag value changes.
The process of updating an entity using optimistic concurrency is something like the following:
- You fetch the entity from the table.
- You make changes to the entity on the client side (say increase the
version
property). - You send the update request to Table Storage. When sending the update request, you will need to include the ETag value of the fetched entity.
When ETag value is included in the update request, Table Storage compares that value with the current ETag value of the entity.
If both are the same, that means the entity has not been updated since fetched and updates can be done.
If the values are different, then Table Storage returns a Pre Condition failed (412)
error back. In this case, you will need to fetch the entity again and repeat the process.
From this link
:
An entity's ETag provides default optimistic concurrency for update operations. The ETag value is opaque and should not be read or relied upon. Before an update operation occurs, the Table service verifies that the entity's current ETag value is identical to the ETag value included with the update request in the If-Match header. If the values are identical, the Table service determines that the entity has not been modified since it was retrieved, and the update operation proceeds.
If the entity's ETag differs from that specified with the update request, the update operation fails with status code 412 (Precondition Failed). This error indicates that the entity has been changed on the server since it was retrieved. To resolve this error, retrieve the entity again and reissue the request.
To force an unconditional update operation, set the value of the If-Match header to the wildcard character (*) on the request. Passing this value to the operation will override the default optimistic concurrency and ignore any mismatch in ETag values.