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

CosmosDB存储过程:Etag不匹配时抛出异常的实现方案

修改后的存储过程及实现说明

核心修改点

  • 区分创建新文档与Etag匹配更新两种场景:
    • 若传入文档不含指定Etag标识字段(示例中用matchEtag),执行创建操作
    • 若含Etag字段,执行带Etag校验的更新操作,校验失败时抛出明确可捕获的异常
  • 用replaceDocument替代原upsertDocument处理更新逻辑,通过accessCondition设置Etag匹配规则
  • 针对Etag不匹配的412状态码,抛出自定义异常信息,方便Java代码识别处理

修改后的完整代码

function createEvent(items) {
    var collection = getContext().getCollection();
    var collectionLink = collection.getSelfLink();
    var count = 0;

    if (!items) throw new Error("The array is undefined or null.");
    var numItems = items.length;
    if (numItems === 0) {
        getContext().getResponse().setBody(0);
        return;
    }

    tryProcess(items[count], callback);

    function tryProcess(item, callback) {
        var options = { disableAutomaticIdGeneration: false };
        
        // 根据是否携带matchEtag判断操作类型
        if (item.matchEtag) {
            // 更新场景:设置Etag匹配条件
            options.accessCondition = {
                type: "IfMatch",
                condition: item.matchEtag
            };
            // 移除临时Etag字段,避免写入文档
            delete item.matchEtag;
            // 执行带Etag校验的替换操作
            var isAccepted = collection.replaceDocument(collectionLink, item, options, callback);
        } else {
            // 创建场景:执行新增操作(文档已存在则报错)
            var isAccepted = collection.createDocument(collectionLink, item, options, callback);
        }

        if (!isAccepted) getContext().getResponse().setBody(count);
    }

    function callback(err, item, options) {
        if (err) {
            // 捕获Etag不匹配的412错误,抛出明确异常
            if (err.code === 412) {
                throw new Error("Etag mismatch: Target document has been modified by other process.");
            }
            throw err;
        }
        count++;
        if (count >= numItems) {
            getContext().getResponse().setBody(count);
        } else {
            tryProcess(items[count], callback);
        }
    }
}

使用注意事项

  • 参数约定:
    • 创建文档:无需携带matchEtag字段
    • 更新文档:必须携带matchEtag字段,值为目标文档当前的Etag值
  • Java端处理:调用存储过程时,捕获到包含Etag mismatch的异常即可判定为Etag不匹配场景
  • 扩展说明:如果需要创建时允许覆盖已存在文档,可将创建场景的createDocument改回upsertDocument,但保留更新场景的Etag校验逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:01:26