TransactionInProgressException

TL;DR — Uma nova tentativa de TransactWriteItems carregou o mesmo ClientRequestToken que uma tentativa que ainda está em execução. Geralmente, o tempo limite do cliente expira mais rápido do que a conclusão da transação, portanto, a nova tentativa do SDK colide com o original em andamento. Continue tentando novamente com espera - uma nova tentativa posterior após o término original retorna o sucesso idempotente - e ajuste os tempos limite para que pelo menos uma nova tentativa ocorra após aproximadamente 5 segundos.

O que significa

TransactionInProgressException: The transaction with the given request token
is already in progress.

ClientRequestToken torna TransactWriteItems idempotente: chamadas idênticas em uma janela de 10 minutos contam como uma transação. Enquanto a primeira tentativa ainda está sendo processada, uma segunda chamada com o mesmo token ainda não pode ser atendida — não é nem uma duplicata de uma transação concluída nem uma nova — então o DynamoDB a rejeita com esta exceção. É um sinal de temporização, não um erro de dados.

Por que isso acontece

  • Tempo limite do cliente menor que a latência da transação — o tempo limite da solicitação é acionado, o SDK tenta novamente e a nova tentativa chega enquanto a transação original ainda está sendo confirmada.
  • Política agressiva de novas tentativas — espera muito curta significa que várias tentativas podem se acumular em uma transação que precisa de alguns segundos.
  • Dois chamadores compartilhando um token — processos separados emitindo deliberadamente (ou acidentalmente) o mesmo ClientRequestToken simultaneamente.

Como corrigir

  1. Deixe as novas tentativas continuarem com espera exponencial — assim que a transação em andamento for concluída, uma nova tentativa com o mesmo token retornará sucesso sem aplicar as escritas duas vezes. Trate esta exceção como passível de nova tentativa.

  2. Ajuste os tempos limite de acordo com a orientação documentada para que uma nova tentativa possa ocorrer após a conclusão da transação:

    • permitir que pelo menos uma nova tentativa seja processada depois de decorridos 5 segundos desde a primeira tentativa;
    • defina o tempo limite por solicitação para cerca de 1 segundo ou mais;
    • mantenha o tempo limite do soquete um pouco abaixo do tempo limite da solicitação;
    • use espera exponencial entre tentativas.
  3. Não gire o token na nova tentativa — gerar um novo ClientRequestToken por tentativa converte silenciosamente as novas tentativas em novas transações (aplicando duas vezes as escritas). Mesma intenção, mesmo token, por até 10 minutos:

    const token = randomUUID(); // one token per logical transaction
    await client.send(new TransactWriteItemsCommand({TransactItems, ClientRequestToken: token}));
  4. Serialize chamadores concorrentes deliberados — se dois workers podem submeter a mesma transação lógica, faça um deles o dono ou encaminhe ambos por uma fila.

  5. Registre o token e o tempo decorrido em cada retry. A orientação dos 5 segundos é documentada — seus logs devem mostrar se os retries chegam cedo demais.

Caminho no DynoTable

Inspecione os itens que uma transação longa toca antes de ajustar timeouts — abra-os com ⌘K e confirme que não há disputa de chave quente vinda de escritores paralelos. O staging (⌘S) permite reexecutar uma transação menor contra dados de dev primeiro.

Estime o custo das escritas transacionais com a calculadora de preços. Troque de perfil com ⌘P; Test Connection em Settings → Profiles. Veja Connect to AWS e Install.

Fontes

Erros relacionados

Referências

Verificado pela última vez em 2026-07-13 contra a documentação oficial da AWS vinculada acima.

Trabalhe com o DynamoDB sem o Console

Um cliente desktop rápido para DynamoDB que roda o SQL de verdade que o DynamoDB não consegue — JOINs, GROUP BY, agregações — com edição visual e um agente de IA com suas próprias chaves do Bedrock.

Teste grátis de 30 dias, sem cartão de crédito — depois o plano Grátis sem limite de tempo.