2013-03-19 24 views
14

Windows Azure開発には本当に新しいもので、Windows Azureストレージテーブルにデータを保存する必要があります。WIndows Azureストレージテーブルを削除して再作成する正しい方法=エラー409競合 - コード:TableBeingDeleted

この表は、Azureストレージドライブにある一部のファイルにクイックルックアップメカニズムを提供するためにのみ存在します。

そこで私が起動したアプリケーションでは、このテーブルを取り込む上で計画していた(つまり、Webアプリケーションのグローバルアプリケーションが起動)

ではなく、変更のためにアプリケーション中にドライブに発生する可能性がある変更を、このテーブルを維持しようとしています実行されていません。または、このドライブは単にリソースのvhdであるため、新しいvhdをアップロードすることがよくあります。

これを維持しようとする面倒ではありません。各アプリケーションの起動時にこのテーブルを再構築すれば十分です。

私は、テーブルがすでに存在するかどうかをチェックし、テーブルを削除してから新しいテーブルを作り直すコードをまとめました。

var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString); 
var tableClient = storageAccount.CreateCloudTableClient(); 
var rmsTable = tableClient.GetTableReference("ResourceManagerStorage"); 
rmsTable.DeleteIfExists(); 
rmsTable.Create(); 

これはうまくいかないと思っていました。次のエラーが表示されます。

The remote server returned an error: (409) Conflict. 

HTTP/1.1 409 Conflict 
Cache-Control: no-cache 
Transfer-Encoding: chunked 
Server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 
x-ms-request-id: c6baf92e-de47-4a6d-82b3-4faec637a98c 
x-ms-version: 2012-02-12 
Date: Tue, 19 Mar 2013 17:26:25 GMT 

166 
<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 
    <code>TableBeingDeleted</code> 
    <message xml:lang="en-US">The specified table is being deleted. Try operation later. 
RequestId:c6baf92e-de47-4a6d-82b3-4faec637a98c 
Time:2013-03-19T17:26:26.2612698Z</message> 
</error> 
0 

これを行う正しい方法は何ですか。あなたがテーブルが削除された時を知らせるために購読できるイベントはありますか?これを実装する最善の方法に関する他の提案はありますか?

答えて

25

投稿者MSDN "テーブルの削除は、完了するまでに少なくとも40秒かかる可能性があります。削除中のテーブルに対して操作を試みると、サービスは状態コード409(競合)を返します。テーブルが削除されていることを示すエラー情報。

これに対処する唯一の方法は、別の名前のテーブルを作成することです。これは、あなたの名前にタイムスタンプまたはGUIDを追加するのと同じくらい簡単です。あなたのゴミを掃除するように注意してください。

+0

また、作成コマンドが成功するまで待つこともできます。 – Igorek

+2

テーブルのサイズやその他の要因によっては、長い時間。 – IngisKahn

+0

訂正ありがとうございます – Igorek

12

あなたが同じテーブル名を使用する必要がある場合は、拡張メソッドを使用することができます

public static class StorageExtensions 
{ 
    public static bool SafeCreateIfNotExists(this CloudTable table, TableRequestOptions requestOptions = null, OperationContext operationContext = null) 
    { 
     do 
     { 
      try 
      { 
       return table.CreateIfNotExists(requestOptions, operationContext); 
      } 
      catch (StorageException e) 
      { 
       if ((e.RequestInformation.HttpStatusCode == 409) && (e.RequestInformation.ExtendedErrorInformation.ErrorCode.Equals(TableErrorCodeStrings.TableBeingDeleted))) 
        Thread.Sleep(1000);// The table is currently being deleted. Try again until it works. 
       else 
        throw; 
      } 
     } while (true); 
    } 
} 

警告!このアプローチを使用するときは、スレッドをブロックするので注意してください。また、サードパーティのサービス(Azure)がこれらのエラーを生成し続けると、デッドループに陥る可能性があります。その理由は、テーブルのロック、サブスクリプションの有効期限、サービスの利用不能などです。

+3

うわー、それは素晴らしい考えではない。通常、ロジックがサードパーティのサービスに依存している間、私はwhile(true)を避けようとします。 while(retryCnt> 0)ここで良いでしょう。 –

+1

もちろん、いくつかのタイムアウトパラメータやハードコードをタイムアウトすることができます。しかし、どんな価値がありますか? 1分、2分、20分? IngisKahnは「...完了するのに少なくとも40秒かかる可能性が高い」と述べた。あなたは高い価値を必要とし、1秒以上待ってもプロセスが完了するかどうかはわかりません。サービスが利用できない場合、または別の問題が存在する場合、MSが同じエラーTableErrorCodeStrings.TableBeingDeletedを返すとは想像できません。誰かがタイムアウトを追加すると、私はかなり高い価値を示唆しています。 – huha

+0

メソッドを非同期にして、 'Thread.Sleep(2000)'を 'await Task.Delay(2000)'に置き換えることができます。スレッドはこのようにブロックされません。 – UserControl

関連する問題