Sebastián Odena
Sebastián Odena

Reputation: 205

Azure Storage Tables - Update Condition Not Satisfied

I'm getting a random Exception when I try to update an entity on a storage table. The exception I get is

System.Data.Services.Client.DataServiceRequestException: An error occurred while processing this request. ---> System.Data.Services.Client.DataServiceClientException: {"odata.error":{"code":"UpdateConditionNotSatisfied","message":{"lang":"en-US","value":"The update condition specified in the request was not satisfied.\nRequestId:2a205f10-0002-013b-028d-0bbec8000000\nTime:2015-10-20T23:17:16.5436755Z"}}} ---

I know that this might be a concurrency issue, but the thing is that there's no other process accessing that entity.

From time to time I get dozens of these exceptions, I restart the server and it starts working fine again.

public static class StorageHelper
    {
        static TableServiceContext tableContext;

        static CloudStorageAccount storageAccount;

        static CloudTableClient CloudClient;



        static StorageHelper()
        {

                storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
                CloudClient = storageAccount.CreateCloudTableClient();
                tableContext = CloudClient.GetTableServiceContext();
                tableContext.IgnoreResourceNotFoundException = true;
            }



public static void Save(int myId,string newProperty,string myPartitionKey,string myRowKey){
     var entity = (from j in tableContext.CreateQuery<MyEntity>("MyTable")
                          where j.PartitionKey == myId
                          select j).FirstOrDefault();


            if (entity != null)
            {
                entity.MyProperty= myProperty;
                tableContext.UpdateObject(entity);
                tableContext.SaveChanges();


            }
            else
            {
                entity = new MyEntity();
                entity.PartitionKey =MyPartitionKey;
                entity.RowKey =MyRowKey;
                entity.MyProperty= myProperty;
                tableContext.AddObject("MyTable", entity);
                tableContext.SaveChanges();
            }
}

Upvotes: 3

Views: 5563

Answers (3)

Emily Gerner
Emily Gerner

Reputation: 2457

  1. The code you've posted uses the very old table layer which is now obsolete. We strongly recommend you update to a newer version of the storage library and use the new table layer. See this StackOverflow question for more information. Also note that if you're using a very old version of the storage library these will eventually stop working as the service version they're using is going to be deprecated service side.

  2. We do not recommend that customers reuse TableServiceContext objects as has been done here. They contain a variety of tracking that can cause performance issues as well as other adverse effects. These kind of limitations is part of the reason we recommend (as described above) moving to the newer table layer. See the how-to for more information.

  3. On table entity update operations you must send an if-match header indicating an etag. The library will set this for you if you set the entity's etag value. To update no matter what the etag of the entity on the service, use "*".

Upvotes: 1

Mayur Dhingra
Mayur Dhingra

Reputation: 1577

While updating your entity, set ETag = "*". Your modified code should look something like this -

if (entity != null)
{
    entity.MyProperty= "newProperty";
    tableContext.UpdateObject(entity);
    tableContext.SaveChanges();
}

Upvotes: 0

juvchan
juvchan

Reputation: 6255

I suggest you can consider using the Transient Fault Handling Application Block from Microsoft's Enterprise Library to retry when your application encounters such transient fault in Azure to minimize restarting the server every time when the same exception occurs.

https://msdn.microsoft.com/en-us/library/hh680934(v=pandp.50).aspx

Upvotes: 0

Related Questions