TransactionInProgressException
TL;DR — Un reintento de TransactWriteItems llevó el mismo ClientRequestToken que un intento que todavía se está ejecutando. Esto suele ser tu cliente agotando su tiempo más rápido de lo que la transacción se completa, así que el reintento del SDK colisiona con el original en curso. Sigue reintentando con backoff — un reintento posterior, una vez que el original termina, devuelve el éxito idempotente — y ajusta los tiempos de espera para que al menos un reintento aterrice tras ~5 segundos.
Qué significa
TransactionInProgressException: The transaction with the given request token
is already in progress.ClientRequestToken hace que TransactWriteItems sea idempotente: las llamadas idénticas dentro de una ventana de 10 minutos cuentan como una sola transacción. Mientras el primer intento aún se procesa, una segunda llamada con el mismo token no se puede responder todavía — no es ni un duplicado de una transacción completada ni una nueva — así que DynamoDB la rechaza con esta excepción. Es una señal de temporización, no un error de datos.
Por qué ocurre
- Tiempo de espera del cliente más corto que la latencia de la transacción — el tiempo de espera de la petición se dispara, el SDK reintenta, y el reintento llega mientras la transacción original aún se está confirmando.
- Política de reintentos agresiva — un backoff muy corto significa que varios reintentos pueden apilarse sobre una transacción que necesita unos segundos.
- Dos llamantes compartiendo un token — procesos separados que emiten deliberadamente (o accidentalmente) el mismo
ClientRequestTokende forma concurrente.
Cómo solucionarlo
Deja que los reintentos continúen con backoff exponencial — una vez que la transacción en curso se completa, un reintento con el mismo token devuelve éxito sin aplicar las escrituras dos veces. Trata esta excepción como reintentable.
Ajusta los tiempos de espera según la guía documentada para que un reintento pueda aterrizar tras asentarse la transacción:
- permite que al menos un reintento se procese tras haber transcurrido 5 segundos desde el primer intento;
- establece el tiempo de espera por petición en aproximadamente 1 segundo o más;
- mantén el tiempo de espera del socket ligeramente por debajo del tiempo de espera de la petición;
- usa backoff exponencial entre intentos.
No rotes el token en el reintento — generar un
ClientRequestTokennuevo por intento convierte silenciosamente los reintentos en nuevas transacciones (aplicando las escrituras por duplicado). Misma intención, mismo token, durante hasta 10 minutos:const token = randomUUID(); // one token per logical transaction await client.send(new TransactWriteItemsCommand({TransactItems, ClientRequestToken: token}));Serializa los llamantes concurrentes deliberados — si dos workers pueden enviar la misma transacción lógica, haz que uno sea el propietario o enruta ambos por una cola.
Si las transacciones tardan lo suficiente como para superar los tiempos de espera, comprueba en qué están entrando en contención — la aplicación de escritorio DynoTable te permite inspeccionar los Items implicados, y la calculadora de precios de DynamoDB muestra lo que cuesta la capacidad de escritura duplicada de las escrituras transaccionales.
Errores relacionados
- IdempotentParameterMismatchException — mismo token, carga diferente.
- TransactionCanceledException — la propia transacción falló.
- TransactionConflictException — conflicto a nivel de Item con otra transacción.
- Ejemplo de código: TransactWriteItems in Node.js — muestra el uso de ClientRequestToken.
- Aprende: DynamoDB transactions
References
- TransactWriteItems — Amazon DynamoDB API Reference
- Amazon DynamoDB Transactions: How it works — Amazon DynamoDB Developer Guide
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Última verificación el 2026-07-13 con la documentación oficial de AWS enlazada arriba.