Question

I am developing a node.js application on Windows Azure Websites (IISNode) and have installed the Azure SDK module for node.js my question is how to use the etag or timestamp field in table storage.

Is it a matter of "me" doing something e.g:

if (entities[0].Timestamp == newEntity.Timestamp)
    // commit this update because we are dealing with the latest copy of this entity
else
    // oops! one of the entities is newer than the other, better not save it

Or do I need to listen for a error returned by the tableService.updateEntity( ... for an error returned or something ?

Any help or advice appreciated

Was it helpful?

Solution

As Neil mentioned good practice is to let table service handles the concurrency related stuff.

When we fetch the entity from the table service using the client library, library will store the ETag associated with the entity (which present in the response from the service for the entity) in an EntityDescriptior instance (EntityDescriptor is an object maintained by the library for each entity instance in the context)

When you submit a request to update an entity, sdk will prepare HTTP request with body as entity serialized to XML and ETag header of the request as the ETag value stored in the entity descriptor corresponding to the entity.

When the table service receives this request for updating the entity instance, it checks whether the ETag in the request matches with the ETag currently associated with entity in the table storage (the ETag associated with the entity stored in the service changes if some other update happened before receiving your update request), if it does not matches service returns pre-condition failed/conflict error by setting Http status code in the response to 412 or 409.

bool done = true;
while (!done)
{
    Stat statistics = _context.Execute<Stat>(new Uri("https://management.core.windows.net/<subscription-id>/services/storageservices/StatEntity?RowKey=..&PartitionKey=..").FirstOrDefault();

    try
    {
        // TODO: Update the entity, e.g. statistics.ReadCount++
        _context.UpdateObject(statistics);
        _context.SaveChanges();
        // success
        break;
    }
    catch (DataServiceRequestException exception)
    {
        var response = exception.Response.FirstOrDefault();
        if (response != null && (response.StatusCode == 412 || response.StatusCode == 409))
        {
            // Concurrency Exception - Entity Updated in-between
            // by another thread, Fetch the latest _stat entity and repeat operation
        }
        else
        {
            // log it and come out of while loop
            break;
        }
    }
    catch (Exception)
    {
        // log it and come out of while loop
        break;
    }
}

OTHER TIPS

The ETag is used for optimistic concurrency during updates. The ETag is set automatically when you retrieve an entity and is uploaded automatically when you update that queried entity. The update would fail if the entity has in the meantime been updated by another thread. The updateEntity method has an optional parameter, checkEtag, that can be used to modify this behavior by allowing you to specigy that the update should succeed regardless of whether or not another thread has updated the record - thereby overriding the optimistic concurrency.

The Windows Azure Storage Service REST API is the definitive interface to Windows Azure Storage, and htis is the documentation to go to when you want to understand the API capabilities of the service. The documention describing ETag, in general, is here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top