You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Blob Storage中Etag乐观锁失效:旧Etag仍可执行SetMetaDataAsync

Azure Blob容器Etag乐观锁未生效?我来帮你排查!

我之前也踩过这个一模一样的坑!你遇到的问题核心原因很明确:你在第二次调用SetMetaDataAsync时,没有显式指定Etag校验的访问条件。Azure Blob存储的乐观锁机制不是自动触发的,必须通过AccessCondition(旧SDK)或BlobRequestConditions(新SDK)明确告诉服务端“只有当Etag匹配我指定的值时,才允许更新”,否则服务端会直接执行更新,完全不做校验。

你可能遗漏的关键代码步骤

看你给出的代码片段,应该是没把旧Etag传入访问条件参数。这里分两种SDK版本给你正确的写法:

旧版SDK(Microsoft.Azure.Storage.Blob)

var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("你的容器名");

// 先获取容器当前的Etag(第一次操作前)
await container.FetchAttributesAsync();
string oldEtag = container.Properties.ETag;

// 第一次更新元数据(此时Etag会变更)
container.Metadata.Add("key1", "value1");
await container.SetMetadataAsync();

// 第二次更新,这里必须传入旧Etag的校验条件!
AccessCondition condition = AccessCondition.GenerateIfMatchCondition(oldEtag);
try
{
    container.Metadata["key1"] = "value2";
    await container.SetMetadataAsync(condition, null, null);
}
catch (StorageException ex)
{
    if (ex.RequestInformation.HttpStatusCode == 412)
    {
        // 预条件失败,说明Etag不匹配,处理冲突逻辑
        Console.WriteLine("元数据已被其他请求修改,乐观锁生效!");
    }
}

新版SDK(Azure.Storage.Blobs)

如果用的是最新的SDK,API有变化,需要用BlobRequestConditions:

var blobServiceClient = new BlobServiceClient("你的连接字符串");
var containerClient = blobServiceClient.GetBlobContainerClient("你的容器名");

// 获取旧Etag
var containerProperties = await containerClient.GetPropertiesAsync();
string oldEtag = containerProperties.ETag.ToString();

// 第一次更新
await containerClient.SetMetadataAsync(new Dictionary<string, string> { {"key1", "value1"} });

// 第二次更新,指定IfMatch条件
var requestConditions = new BlobRequestConditions { IfMatch = new ETag(oldEtag) };
try
{
    await containerClient.SetMetadataAsync(new Dictionary<string, string> { {"key1", "value2"} }, requestConditions);
}
catch (RequestFailedException ex)
{
    if (ex.Status == 412)
    {
        Console.WriteLine("乐观锁触发:元数据已被修改!");
    }
}

额外要注意的细节

  • 确保你校验的是容器的Etag,而不是容器内Blob的Etag——容器和Blob的Etag是完全独立的,互相不影响。
  • 当Etag校验失败时,服务端会返回412 Precondition Failed状态码,一定要捕获这个异常来处理冲突场景,比如提示用户重试或者合并变更。

内容的提问来源于stack exchange,提问作者Justin Self

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:31:44