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

£可爱£侵袭症+ 提交于 2021-01-27 04:42:09

问题


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.


回答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.




回答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); 
}



回答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!



来源:https://stackoverflow.com/questions/44799524/azure-table-storage-throwing-exception-on-insert-409-conflict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!