为了实现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);
答案 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。