Gravação condicional no DynamoDB em Node.js (AWS SDK v3)

Uma gravação condicional anexa uma ConditionExpression a um PutItem, UpdateItem ou DeleteItem: o DynamoDB a avalia contra o item atual e aplica a gravação apenas se ela for verdadeira — atomicamente, sem race de read-modify-write. É o primitivo de optimistic locking do DynamoDB. Este exemplo protege uma atualização com uma verificação de versão.

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;
  }
}

Explicação

  • ConditionExpression — verificada contra o item armazenado atomicamente com a gravação. Funções disponíveis: attribute_exists, attribute_not_exists, attribute_type, contains, begins_with, size, mais comparadores (=, <>, <, >, <=, >=, BETWEEN, IN) e AND/OR/NOT.
  • Os dois idiomas de trabalho:
    • attribute_exists(#key) em uma atualização = "somente-atualizar, nunca criar". Sem ele, UpdateItem em uma chave ausente cria o item silenciosamente (o bug de upsert acidental).
    • attribute_not_exists(#key) em um put = "somente-criar, nunca sobrescrever" — mostrado na página do PutItem.
  • Optimistic locking — leia o item (versão 7), depois grave com #version = :expectedVersion ao passar para 8. Dois gravadores concorrentes não podem ambos vencer; o perdedor recebe ConditionalCheckFailedException, relê e tenta de novo na nova versão.
  • ReturnValuesOnConditionCheckFailure: 'ALL_OLD' — coloca o item atual na exceção (err.Item, marshalled), poupando o GetItem de acompanhamento após uma verificação falha. Ele consome nenhuma capacidade de leitura; uma gravação condicional falha ainda cobra sua tentativa de gravação.
  • Tudo aqui recebe um alias (#versionVersion) via ExpressionAttributeNames, então palavras reservadas nunca atrapalham.

Faça visualmente

Condition expressions são exatamente o que o DynamoDB Expression Builder constrói — escolha a função, obtenha a expressão + mapas de nome/valor como código executável.

Para editar itens com expressões geradas e revisáveis em vez de placeholders digitados à mão — baixe o DynoTable.

Exemplos relacionados

References

Última verificação em 2026-07-13 contra a documentação oficial da AWS vinculada acima.

Trabalhe com o DynamoDB sem o Console

O DynoTable é um cliente desktop rápido para o DynamoDB — navegue pelas tabelas, execute consultas no estilo SQL e edite itens localmente.