Azure 存储 blob 的乐观并发始终引发 HTTP 412



为了实现 Azure 存储 blob 的乐观并发,我正在根据 blob 属性中的 ETag 值构造一个If-Match 访问条件

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

对于此示例,我已使用存储资源管理器手动查找 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);

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

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

那应该是:

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

否则,ETag 检查将正确失败,因为没有名称为foo/1的 blob。

上传具有特定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");
}
}

有关更多详细信息,您可以参考本文。

最新更新