2017-06-28 52 views
2

我使用Azure的表存储从我的MVC应用程序日志访客信息,但它有时会抛出以下异常:Azure的表存储在插入引发异常:(409)冲突

[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 

这似乎发生当我第一次访问网站一段时间不活动时,然后当我刷新页面时,页面加载并且每次点击都很好。

这里是造成异常的代码的一部分:

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

更新

正如意见中指明以下两个答案,问题是,有时在页面加载两次并且我正在使用GUID(对用户唯一)作为分区键,并将当前日期时间用作行键,所以这会导致重复的实体并导致异常。

虽然Amor的回答更加深入,但Dogu简单的解决方案就是我使用的解决方案,所以我标记了他的正确答案。感谢大家。

+1

当您收到此错误时,您可以检查实体是否存在吗? –

+0

作为RowKey和PartitionKey使用什么? –

+0

请检查实体是否已经存在Gaurav提到。 –

回答

3

你可以尝试的InsertOrReplace代替Insert避免409,它会插入实体如果它不存在,并取代现有的,如果它存在,它。需要注意的是,它不检查电子标签,所以如果存在具有相同分区密钥和行密钥的现有实体,则无条件地覆盖它。

1

在Azure表存储中,分区键+行键一起充当用于进入表的主键,该组合必须是唯一的。如果您插入的行的分区键和行键已经存在于表中。它会抛出(409)冲突异常。您可以使用以下代码进行确认。

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"); 
    } 
} 

如果再次发生异常,跟踪信息将显示分区键和行键是否已经存在。

您还可以从RequestInformation.ExtendedErrorInformation.ErrorMessage中获取详细的异常消息。

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