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 代理。

30 天免費試用,無需信用卡 — 之後為無時間限制的免費方案。