Azure表存储异常:409冲突意外?

时间:2018-02-20 20:16:23

标签: azure azure-storage azure-table-storage

我正在使用WindowsAzure.Storage nuget软件包版本9.0.0。

Install-Package WindowsAzure.Storage -Version 9.0.0

以下代码(table.CreateIfNotExistsAsync())抛出错误:远程服务器返回错误:(409)冲突。

CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference(tableName);
try
{
    if (await table.CreateIfNotExistsAsync())
    {
        log.Info(string.Format("Created Table named: {0}", tableName));
    }
}
catch (StorageException)
{
    log.Error("If you are running with the default configuration please make sure you have started the storage emulator. Press the Windows key and type Azure Storage to select and run it from the list of applications - then restart the sample.");
    throw;
}

return table;

如果我检查StorageException详细信息,我会收到以下消息:指定的表已存在。

堆栈追踪:

   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync[T](IAsyncResult result) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:line 57

enter image description here

此代码可以正常工作:

CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference(tableName);

try
{
    //if (await table.CreateIfNotExistsAsync())
    //{
    //    log.Info(string.Format("Created Table named: {0}", tableName));
    //}

    if (!table.Exists())
    {
        await table.CreateAsync();

        log.Info(string.Format("Created Table named: {0}", tableName));
    }
}
catch (StorageException)
{
    log.Error("If you are running with the default configuration please make sure you have started the storage emulator. Press the Windows key and type Azure Storage to select and run it from the list of applications - then restart the sample.");
    throw;
}

return table;

我知道我有已经存在的表,但它们目前尚未被删除。为什么我收到此错误?由于表确实存在,我希望执行和存在检查并返回true,而不是抛出存储异常。

修改:这就是我创建CloudStorageAccount的方式

public static CloudStorageAccount CreateStorageAccountFromConnectionString(string storageConnectionString)
{
    CloudStorageAccount storageAccount;
    try
    {
        storageAccount = CloudStorageAccount.Parse(storageConnectionString);
    }
    catch (FormatException fe)
    {
        log.Error("Invalid storage account information provided. Please confirm the AccountName and AccountKey are valid in the app.config file - then restart the application.", fe);
        throw;
    }
    catch (ArgumentException ae)
    {
        log.Error("Invalid storage account information provided. Please confirm the AccountName and AccountKey are valid in the app.config file - then restart the sample.", ae);
        throw;
    }

    return storageAccount;
}

存储连接字符串如下所示:

<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=something;AccountKey=somekeygoeshere==" />

2 个答案:

答案 0 :(得分:1)

你是如何创建CloudStorageAccount对象的?我认为它可能是通过SAS创建的,它没有列表权限,因此table.Exists()始终为每个存储REST API设计返回false,以免将此类信息泄露给未经授权的用户。 table.CreateIfNotExistsAsync()没有遇到此问题的原因是该方法直接调用Create Table REST API而没有事先进行List Tables检查,并且故意在table.CreateIfNotExistsAsync()方法中吞并409 Conflict异常(为了实现“如果不存在则创建”功能,因为409冲突异常意味着该表已经存在,因此该方法可以忽略该错误而不执行任何操作。)

如果我的上述理论适用于您的情况,请使用具有列表表权限的SAS而不是现有SAS,或直接使用共享帐户密钥创建CloudStorageAccount对象。

答案 1 :(得分:1)

一个不错的解决方法是:

if (!container.Exists())
        {
            container.CreateIfNotExists();
        }