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

问题描述 投票:2回答:3

我正在使用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==" />
azure azure-storage azure-table-storage
3个回答
7
投票

CreateIfNotExists正在抛出异常。 CloudBlobContainer.CreateIfNotExistsCloudTable.CreateIfNotExists方法的实施发生了变化。

7.1.2存储客户端库中的实现如下:

  1. 进行调用以检查存储容器或表是否存在(HTTP HEAD请求)。
  2. 如果它存在什么都不做。
  3. 如果它不存在,则调用以创建容器或表。

在存储客户端库8.1.1中,实现如下:

  1. 调用以创建容器或表(HTTP PUT请求)。
  2. 如果返回错误(HTTP 409),因为容器或表已存在,则不执行任何操作。处理错误。
  3. 如果容器或表不存在,则create将成功。

我检查了9.0,这种行为仍然存在


1
投票

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

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


1
投票

一个很好的解决方法可能是:

if (!container.Exists())
        {
            container.CreateIfNotExists();
        }
© www.soinside.com 2019 - 2024. All rights reserved.