Node.js (AWS SDK v3) での DynamoDB 条件付き書き込み

条件付き書き込みは、PutItemUpdateItemDeleteItemConditionExpression を付けます。DynamoDB はそれを現在のアイテムに対して評価し、条件が成立する場合にのみ書き込みを適用します。アトミックで、read-modify-write の競合はありません。これは 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;
  }
}

Explanation

  • ConditionExpression — 書き込みとアトミックに、保存されたアイテムに対してチェックされます。利用可能な関数: attribute_existsattribute_not_existsattribute_typecontainsbegins_withsize、加えて比較演算子(=<><><=>=BETWEENIN)と AND/OR/NOT
  • 2つの主力イディオム:
    • 更新での attribute_exists(#key) = 「更新のみ、決して作成しない」。これがないと、存在しないキーへの UpdateItem はアイテムを静かに作成します(意図しないアップサートのバグ)。
    • プットでの attribute_not_exists(#key) = 「作成のみ、決して上書きしない」— PutItem ページで示しています。
  • 楽観的ロック — アイテム(バージョン7)を読み取り、8 に上げながら #version = :expectedVersion で書き込みます。2つの並行する書き込み側が両方とも勝つことはありません。負けた側は ConditionalCheckFailedException を受け取り、再読み取りして新しいバージョンでリトライします。
  • ReturnValuesOnConditionCheckFailure: 'ALL_OLD'現在のアイテムを例外に載せ(err.Item、マーシャリング済み)、失敗チェック後の後続 GetItem を省きます。読み取りキャパシティは消費しません。失敗した条件付き書き込みでも、書き込みの試行分は課金されます。
  • ここではすべてが ExpressionAttributeNames を介してエイリアス化されている(#versionVersion)ため、予約語に噛まれることはありません。

Do it visually

条件式はまさに DynamoDB Expression Builder が構築するものです。関数を選べば、式と name/value マップが実行可能なコードとして得られます。

手入力のプレースホルダーの代わりに、生成された、レビュー可能な式でアイテムを編集するには — DynoTable をダウンロードしてください。

References

最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。

Console なしで DynamoDB を扱う

DynoTable は DynamoDB 向けの高速なデスクトップクライアントです — テーブルを閲覧し、SQL スタイルのクエリを実行し、アイテムをローカルで編集できます。