Azure存储Blob的乐观并发总是抛出HTTP 412

时间:2018-10-01 19:02:12

标签: .net azure

为了实现Azure存储Blob的乐观并发,我正在基于Blob属性中的ETag值构造一个 If-Match AccessCondition

如果另一个进程已更新Blob,则Blob服务应返回HTTP 412(失败的前提条件)状态消息。但是,该服务始终返回此412状态。

在此示例中,我使用Storage Explorer手动查找了ETag值。

重现该问题的最小代码段是:

var storage = CloudStorageAccount.Parse(connectionString);

var blobClient = storage.CreateCloudBlobClient();

var container = blobClient.GetContainerReference("foo");

var blob = container.GetBlockBlobReference("foo/1");

await blob.UploadTextAsync(
          "test", 
           Encoding.UTF8,
           AccessCondition.GenerateIfMatchCondition("\"0x1A52537587A1234\""),
           new BlobRequestOptions(),
           null);

2 个答案:

答案 0 :(得分:0)

当您上传具有特定ETAG值的Blob时,它将首次生效。但是,当您第二次使用相同的ETAG上传Blob时,将引发412错误。因为一旦您操作了Blob,它的ETAG就会更新。

Blob和容器的乐观并发性

对此类对象执行更新的用户可以发送原始ETag和条件标头,以确保仅在满足特定条件时才会发生更新-在这种情况下,条件是需要存储服务以确保更新请求中指定的If-Match的值与存储服务中存储的ETag头相同。

// Retrieve Etag from the response of an earlier UploadText blob operation.
string orignalETag = blockBlob.Properties.ETag;
// This code simulates an update by a third party.
string helloText = "Blob updated by a third party.";
// No etag, provided so orignal blob is overwritten (thus generating a new etag)
blockBlob.UploadText(helloText);
Console.WriteLine("Blob updated. Updated ETag = {0}", blockBlob.Properties.ETag);
// Now try to update the blob using the orignal ETag provided when the blob was created
try
{
     Console.WriteLine("Trying to update blob using orignal etag to generate if-match access condition");
     blockBlob.UploadText(helloText,accessCondition:
     AccessCondition.GenerateIfMatchCondition(orignalETag));
}
catch (StorageException ex)
{
     if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
     {
          Console.WriteLine("Precondition failure as expected. Blob's orignal etag no longer matches");
     }
}

有关更多详细信息,您可以参考此article

答案 1 :(得分:0)

问题是我不小心使用了错误的blobName

var blob = container.GetBlockBlobReference("foo/1"); 

应该是:

var blob = container.GetBlockBlobReference("1");

否则ETag检查将​​正确失败,因为不存在名称为foo/1的blob。