Node.js 中的 DynamoDB 条件写入(AWS SDK v3)
条件写入会给 PutItem、UpdateItem 或 DeleteItem 附加一个 ConditionExpression:DynamoDB 会针对当前项目对它求值,仅在成立时才应用该写入——原子地进行,没有读-改-写竞态。这是 DynamoDB 的乐观锁原语。本示例用一次版本检查来保护一次更新。
Code
import {DynamoDBClient, UpdateItemCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
// Update the item only if nobody changed it since we read version 7.
const command = new UpdateItemCommand({
TableName: 'Music',
Key: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'Cubano Chant'}
},
UpdateExpression: 'SET #upd0 = :updValue0, #version = :newVersion',
ConditionExpression: 'attribute_exists(#cond0) AND #version = :expectedVersion',
ExpressionAttributeNames: {
'#upd0': 'Genre',
'#version': 'Version',
'#cond0': 'Artist'
},
ExpressionAttributeValues: {
':updValue0': {S: 'Latin Jazz'},
':expectedVersion': {N: '7'},
':newVersion': {N: '8'}
},
ReturnValuesOnConditionCheckFailure: 'ALL_OLD'
});
try {
await client.send(command);
console.log('Updated to version 8');
} catch (err) {
if (err.name === 'ConditionalCheckFailedException') {
// With ReturnValuesOnConditionCheckFailure: 'ALL_OLD', the current item
// rides back on the exception — no extra read to see what beat you.
console.log('Lost the race — item is now:', err.Item);
} else {
throw err;
}
}说明
ConditionExpression— 与写入原子地一起针对已存储项目进行检查。可用函数:attribute_exists、attribute_not_exists、attribute_type、contains、begins_with、size,外加比较符(=、<>、<、>、<=、>=、BETWEEN、IN)以及AND/OR/NOT。- 两个主力惯用法:
- 在更新上使用
attribute_exists(#key)= "仅更新,绝不创建"。没有它,对缺失键的UpdateItem会静默地创建该项目(意外的 upsert bug)。 - 在put上使用
attribute_not_exists(#key)= "仅创建,绝不覆盖"——见 PutItem 页面。
- 在更新上使用
- 乐观锁 — 读取项目(版本 7),然后在把版本提升到 8 的同时以
#version = :expectedVersion写入。两个并发写入者不可能同时获胜;失败者会得到ConditionalCheckFailedException,随后重新读取并基于新版本重试。 ReturnValuesOnConditionCheckFailure: 'ALL_OLD'— 把当前项目放在异常上(err.Item,已 marshalled),省去失败检查后再做一次GetItem。它不消耗读取容量;失败的条件写入仍会对该次写入尝试计费。- 这里的一切都通过
ExpressionAttributeNames做了别名(#version→Version),因此保留字永远不会咬到你。
可视化操作
条件表达式正是 DynamoDB Expression Builder 所构建的——选择函数,即可获得表达式外加名称/值映射,作为可运行代码。
想用生成的、可审阅的表达式来编辑项目,而不是手打的占位符——请下载 DynoTable。
相关示例
- Python 中的 DynamoDB 条件写入 — 用 boto3 完成同样的乐观锁。
- 使用 AWS CLI 的 DynamoDB 条件写入 — 在 shell 中完成同样的乐观锁。
- Node.js 中的 DynamoDB PutItem — 仅创建的
attribute_not_existsput。 - DynamoDB 条件表达式 — 每个函数,配以模式。
- 在多个属性上强制唯一性 — 条件 + 事务的组合。
- DynamoDB ConditionalCheckFailedException — 当失败的检查是预期之内时,以及如何低成本地处理它。
References
- UpdateItem — Amazon DynamoDB API Reference
- Condition expressions — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Last verified 2026-07-13 against the official AWS documentation linked above.