Azure Table Storage throwing exception on Insert: (409) Conflict

15,772

Solution 1

You could try InsertOrReplace instead of Insertto avoid 409, it is going to insert the entity if it does not exist and replace the existing one if it exists. The caveat with that is it does not check eTag s, so if there is an existing entity with the same partition key and row key it unconditionally overwrites it.

Solution 2

In Azure Table Storage, The Partition Key + the Row Key together act as a primary key for that entry into the table, this combination must be unique. If you insert a row whose Partition Key and Row Key are already exist in the table. It will throw (409) Conflict exception. You could confirm it using following code.

var visit = new TrackerVisitEntity(id, url, referer);

var insertOperation = TableOperation.Insert(visit);
try
{
    _table.Execute(insertOperation);
}
catch (StorageException ex)
{
    Trace.TraceInformation(string.Format("PartitionKey:{0},RowKey:{1}", visit.PartitionKey,visit.RowKey));
    TableOperation retrieveOperation = TableOperation.Retrieve<TrackerVisitEntity>(visit.PartitionKey, visit.RowKey);
    TableResult retrievedResult = _table.Execute(retrieveOperation);
    if (retrievedResult.Result != null)
    {
        Trace.TraceInformation("The entity is already exists in Table");
    }
}

If the exception happens again, the trace information will show that whether Partition Key and Row Key are already exist.

You can also get the detail exception message from RequestInformation.ExtendedErrorInformation.ErrorMessage.

catch (StorageException ex)
{
    Trace.TraceInformation(ex.RequestInformation.ExtendedErrorInformation.ErrorMessage); 
}

Solution 3

The way I've handled 409 errors is to catch the specific HttpStatusCode as follows:

public TableResult AddAudioTest(AudioTestModel audioTestModel)
    {
        azureTableStorage = AzureTableStorage.TableConnection("AudioTests");
        TableOperation tableOperation = TableOperation.Insert(audioTestModel);
        try
        {
            TableResult tableInsertResult = azureTableStorage.Execute(tableOperation);
            return tableInsertResult;
        }
        catch (Microsoft.WindowsAzure.Storage.StorageException e) when (e.RequestInformation.HttpStatusCode == 409)
        {
            TableResult tableResult = new TableResult();
            tableResult.HttpStatusCode = e.RequestInformation.;
            tableResult.Result = e.Message;
            return tableResult;
        }
    }

Hope this helps!

Share:
15,772
littlecharva
Author by

littlecharva

Updated on June 18, 2022

Comments

  • littlecharva
    littlecharva about 2 years

    I'm using Azure Table Storage to log visitor information from my MVC app, but it sometimes throws the following exception:

    [WebException: The remote server returned an error: (409) Conflict.]
       System.Net.HttpWebRequest.GetResponse() +1399
       Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:677
    
    [StorageException: The remote server returned an error: (409) Conflict.]
       Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:604
       Microsoft.WindowsAzure.Storage.Table.TableOperation.Execute(CloudTableClient client, CloudTable table, TableRequestOptions requestOptions, OperationContext operationContext) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Table\TableOperation.cs:44
    

    It seems to happen when I first visit the website after a period of inactivity, then when I hit refresh, the page loads and every click from then on is fine.

    Here is the part of the code that's causing the exception:

      var visit = new TrackerVisitEntity(id, url, referer);
      var insertOperation = TableOperation.Insert(visit);
      _table.Execute(insertOperation);
    

    Update

    As identified in the comments AND both answers below, the problem is that sometimes the page is loaded twice in quick succession, and I'm using a GUID (unique to the user) as the partition key, and the current datetime as the row key, so this is causing duplicate entities and causing the exception.

    Although Amor's answer was more indepth, Dogu's simple solution was the one I used, so I marked his correct. Thanks everyone.

  • AskMe
    AskMe about 6 years
    How to add multiple image's partitionkey and rowkey without replacing it?
  • Martin Connell
    Martin Connell over 4 years
    It seems that the Execute method is inconsistent in when it throws and when it returns with TableResult.Result set to null + TableResult.HttpStatusCode set to 4xx. I get the former case with 412 errors and the latter with 404 errors.