TransactionInProgressException

TL;DR — 一次 TransactWriteItems 重试携带了与一次_仍在执行_的尝试相同的 ClientRequestToken。这通常是你的客户端超时快于事务完成,因此 SDK 的重试与进行中的原始请求碰撞了。用退避继续重试——在原始请求完成后的一次较晚重试会返回幂等的成功——并调优超时,使至少一次重试在约 5 秒后落地。

含义

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

ClientRequestTokenTransactWriteItems 具有幂等性:10 分钟窗口内相同的调用算作一个事务。当第一次尝试仍在被处理时,用相同 token 的第二次调用还无法被应答——它既不是一个已完成事务的重复,也不是一个新的——因此 DynamoDB 用这个异常拒绝它。它是一个时序信号,而非数据错误。

为什么会发生

  • 客户端超时短于事务延迟——请求超时触发,SDK 重试,而重试在原始事务仍在提交时到达。
  • 激进的重试策略——很短的退避意味着几次重试可能堆到一个需要几秒的事务上。
  • 两个调用者共享一个 token——不同的进程有意(或无意)并发地发出同一个 ClientRequestToken

如何修复

  1. 让重试用指数退避继续——一旦进行中的事务完成,用相同 token 的一次重试会返回成功,而不会把写入应用两次。把这个异常当作可重试。

  2. 按文档指引调优超时,使一次重试能在事务稳定后落地:

    • 允许至少一次重试在自第一次尝试起过了 5 秒之后被处理;
    • 把逐请求超时设为大约 1 秒或更高
    • 让套接字超时略低于请求超时;
    • 在尝试之间使用指数退避。
  3. 不要在重试时轮换 token——每次尝试生成一个新的 ClientRequestToken 会悄悄地把重试变成_新事务_(把写入应用两次)。相同意图、相同 token,最长 10 分钟:

    const token = randomUUID(); // one token per logical transaction
    await client.send(new TransactWriteItemsCommand({TransactItems, ClientRequestToken: token}));
  4. 串行化有意的并发调用者——如果两个 worker 可能提交同一个逻辑事务,就让其中一个成为所有者,或把两者都通过一个队列路由。

如果事务运行得足够久以致触发超时,检查它们在争用什么——DynoTable 桌面应用让你检查涉及的项目,而 DynamoDB 定价计算器会显示事务性写入翻倍的写入容量的成本。

DynoTable 中的路径

在调整超时之前检查长事务涉及的项目 - 使用 ⌘K 打开它们并确认并行编写器没有热键争用。暂存 (⌘S) 允许你首先针对开发数据重播较小的事务。使用 pricing calculator 估算事务写入成本。使用 ⌘P 切换配置文件; 在“设置”→“配置文件”上测试连接。参见连接 AWS安装

来源

相关错误

参考资料

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。