Azure Table Storageを使用してMVCアプリからの訪問者情報をログに記録していますが、次の例外がスローされることがあります。
[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
しばらく操作を行わなかった後、最初にWebサイトにアクセスしたときに発生するようです。その後、更新を押すと、ページが読み込まれ、それ以降はクリックするたびに問題が発生します。
例外の原因となっているコードの部分は次のとおりです。
var visit = new TrackerVisitEntity(id, url, referer);
var insertOperation = TableOperation.Insert(visit);
_table.Execute(insertOperation);
更新
以下のコメントと両方の回答で特定されているように、問題は、ページが2回連続して読み込まれることがあり、パーティションキーとしてGUID(ユーザー固有)を使用していることです。 、および行キーとしての現在の日時。これにより、エンティティが重複し、例外が発生します。
アモールの答えはもっと詳細でしたが、土偶の簡単な解決策が私が使用したものだったので、私は彼の正解をマークしました。みんな、ありがとう。
409を回避するためにInsertOrReplace
の代わりにInsert
を試すことができます。エンティティが存在しない場合は挿入し、存在する場合は既存のエンティティを置き換えます。それに関する警告は、eTagをチェックしないため、同じパーティションキーと行キーを持つ既存のエンティティがある場合、無条件に上書きします。
Azure Table Storageでは、パーティションキーと行キーが一緒になってテーブルへのエントリの主キーとして機能します。この組み合わせは一意である必要があります。パーティションキーと行キーがすでにテーブルに存在する行を挿入する場合。 (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);
}
私が409のエラーを処理した方法は、次のように特定のcatch
をHttpStatusCode
することです。
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;
}
}
お役に立てれば!