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

DynamoDB无需读库校验实现movies_watched map存储唯一影片的方法

实现方案

完全可以不用提前读取校验,直接使用DynamoDB原生的条件写入能力就能满足你的需求,实现原子性的唯一影片写入,避免并发冲突。

核心逻辑是在写入请求中加入ConditionExpression,判定待新增的影片ID对应的map键不存在时才执行写入,请求如果触发条件不满足的异常,就说明该影片已经存在,直接处理异常即可,不需要额外做读操作校验。

以下是Node.js环境下的代码示例:

const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, UpdateCommand } = require("@aws-sdk/lib-dynamodb");

// 初始化DynamoDB客户端
const client = new DynamoDBClient({ region: "替换为你的AWS区域" });
const docClient = DynamoDBDocumentClient.from(client);

const addUniqueMovie = async (userId, dob, newMovieId, newMovieInfo) => {
  const params = {
    TableName: "替换为你的表名",
    Key: {
      user_id: userId,
      dob: dob
    },
    // 写入新影片到map对应键位
    UpdateExpression: `SET movies_watched.#movieId = :movieInfo`,
    ExpressionAttributeNames: {
      "#movieId": newMovieId // 用表达式别名规避数字作为属性名的语法问题
    },
    ExpressionAttributeValues: {
      ":movieInfo": newMovieInfo
    },
    // 核心条件:只有该影片ID不存在时才执行写入
    ConditionExpression: `attribute_not_exists(movies_watched.#movieId)`
  };

  try {
    await docClient.send(new UpdateCommand(params));
    return { success: true, msg: "影片新增成功" };
  } catch (error) {
    if (error.name === "ConditionalCheckFailedException") {
      return { success: false, msg: "该影片已存在,无需重复添加" };
    }
    throw error;
  }
}

// 调用示例
addUniqueMovie(1, "1991-09-12", "5", {
  movie_name: "星际穿越",
  movie_released_year: "2014",
  movie_genre: "科幻"
});

注意事项

  • 该操作是原子操作,即使同一时间有多个相同的写入请求,也只会有一个请求执行成功,不会出现重复写入的问题
  • 条件写入的资源开销和普通写入完全一致,不会额外消耗读容量
  • 如果你判断唯一的依据不是影片ID,而是影片名称等其他字段,只需要把对应字段作为map的键,或者额外新增一个字符串集合存储唯一标识,把条件表达式修改为NOT contains(唯一标识集合字段, :待校验值)即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:15:03