AWS DynamoDB putItem写入时如何校验另一行PK是否存在
DynamoDB 新增商品时校验分类存在的可行方案
方案1:使用DynamoDB原生事务写入(强一致,最推荐)
DynamoDB的TransactWriteItems接口支持跨多item的原子操作,你可以在同一个事务里同时完成「分类存在性校验」和「商品写入」两个操作,要么全部成功,要么全部失败,完全避免竞态问题。
事务请求的结构示例(以AWS JS SDK v3为例):
import { DynamoDBClient, TransactWriteItemsCommand } from "@aws-sdk/client-dynamodb"; const client = new DynamoDBClient({}); // 待写入的新商品数据 const newProduct = { PK: { S: "product_xxx" }, SK: { S: "profile" }, Name: { S: "xxx" }, categoryId: { S: "category_1" }, Desc: { S: "xxx" } }; const targetCategoryId = newProduct.categoryId.S; await client.send(new TransactWriteItemsCommand({ TransactItems: [ // 第一个操作:校验分类项真实存在 { ConditionCheck: { TableName: "你的表名", Key: { PK: { S: targetCategoryId }, SK: { S: "meta" } }, // 校验条件:分类项的PK属性存在,即对应分类项真实存在 ConditionExpression: "attribute_exists(PK)" } }, // 第二个操作:写入新商品 { Put: { TableName: "你的表名", Item: newProduct } } ] }));
如果分类不存在,事务会直接抛出TransactionCanceledException异常,商品不会被写入。
方案2:先查询校验再写入(弱一致,适合分类几乎不会被删除的场景)
如果对一致性要求不高,且分类删除操作极少,可以先查询对应的分类项是否存在,查询返回存在后再执行商品写入。
注意:该方案存在竞态风险,如果查询完成到写入完成的时间差内分类被删除,会出现脏数据。
方案3:异步校验补偿(最终一致,适合写入吞吐量高的场景)
如果对写入延迟要求很高,可以先放行商品写入,再通过DynamoDB Streams触发Lambda函数异步校验关联分类是否存在,如果分类不存在则回滚删除对应商品,同时发送业务告警。
该方案为最终一致性,会存在短时间的脏数据窗口,适合对一致性要求低、写入量高的业务场景。
内容的提问来源于stack exchange,提问作者reis12341
相关产品推荐
相关产品推荐

