web-dev-qa-db-ja.com

Windows Azureストレージテーブルを削除して再作成する正しい方法=エラー409の競合-コード:TableBeingDeleted

私はWindowsAzure開発に本当に慣れておらず、WindowsAzureストレージテーブルにいくつかのデータを格納する必要があります。

このテーブルは、実際には、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

これを行う正しい方法は何ですか?テーブルが削除されたときに通知するためにサブスクライブできるイベントはありますか?これを実装するための最良の方法に関する他の提案はありますか?

17
Kramer00

From [〜#〜] msdn [〜#〜] : "テーブルの削除は、完了するまでに少なくとも40秒かかる可能性があることに注意してください。削除中にテーブルに対して操作を試みた場合、サービスはステータスコード409(競合)を返し、テーブルが削除されていることを示す追加のエラー情報が表示されます。」

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

28
IngisKahn

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

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)がこれらのエラーを生成し続けると、デッドループに陥る可能性があります。この理由は、テーブルのロック、サブスクリプションの有効期限、サービスが利用できないなどである可能性があります。

15
huha