TransactionInProgressException
TL;DR — 一次 TransactWriteItems 重試攜帶了與一次_仍在執行_的嘗試相同的 ClientRequestToken。這通常是你的用戶端超時快於事務完成,因此 SDK 的重試與進行中的原始請求碰撞了。用退避繼續重試——在原始請求完成後的一次較晚重試會返回冪等的成功——並調優超時,使至少一次重試在約 5 秒後落地。
這是什麼意思
TransactionInProgressException: The transaction with the given request token
is already in progress.ClientRequestToken 讓 TransactWriteItems 具有冪等性:10 分鐘視窗內相同的呼叫算作一個事務。當第一次嘗試仍在被處理時,用相同 token 的第二次呼叫還無法被應答——它既不是一個已完成事務的重複,也不是一個新的——因此 DynamoDB 用這個異常拒絕它。它是一個時序訊號,而非資料錯誤。
為什麼會發生
- 用戶端超時短於事務延遲——請求超時觸發,SDK 重試,而重試在原始事務仍在提交時到達。
- 激進的重試策略——很短的退避意味著幾次重試可能堆到一個需要幾秒的事務上。
- 兩個呼叫者共享一個 token——不同的程序有意(或無意)並行地發出同一個
ClientRequestToken。
如何修正
讓重試用指數退避繼續——一旦進行中的事務完成,用相同 token 的一次重試會返回成功,而不會把寫入應用兩次。把這個異常當作可重試。
按文件指引調優超時,使一次重試能在事務穩定後落地:
- 允許至少一次重試在自第一次嘗試起過了 5 秒之後被處理;
- 把逐請求超時設為大約 1 秒或更高;
- 讓套接字超時略低於請求超時;
- 在嘗試之間使用指數退避。
不要在重試時輪換 token——每次嘗試生成一個新的
ClientRequestToken會悄悄地把重試變成_新事務_(把寫入應用兩次)。相同意圖、相同 token,最長 10 分鐘:const token = randomUUID(); // one token per logical transaction await client.send(new TransactWriteItemsCommand({TransactItems, ClientRequestToken: token}));序列化有意的並行呼叫者——如果兩個 worker 可能提交同一個邏輯事務,就讓其中一個成為所有者,或把兩者都透過一個佇列路由。
如果事務執行得足夠久以致觸發超時,檢查它們在爭用什麼——DynoTable 桌面應用讓你檢查涉及的項目,而 DynamoDB 定價計算器會顯示事務性寫入翻倍的寫入容量的成本。
DynoTable 中的路徑
在調整超時之前檢查長事務涉及的項目 - 使用 ⌘K 開啟它們並確認並行編寫器沒有熱鍵爭用。暫存 (⌘S) 允許你首先針對開發資料重播較小的事務。使用 pricing calculator 估算事務寫入成本。使用 ⌘P 切換設定檔案; 在“設定”→“設定檔案”上測試連線。參見連線 AWS和安裝。
來源
- TransactWriteItems — Amazon DynamoDB API Reference(2026-07-13 驗證)
- Amazon DynamoDB Transactions: How it works(2026-07-13 驗證)
相關錯誤
- IdempotentParameterMismatchException——相同 token,_不同_載荷。
- TransactionCanceledException——事務本身失敗了。
- TransactionConflictException——與另一個事務的項目級衝突。
- 程式碼示例:TransactWriteItems in Node.js——展示了 ClientRequestToken 的用法。
- 學習:DynamoDB transactions
參考資料
- TransactWriteItems — Amazon DynamoDB API Reference
- Amazon DynamoDB Transactions: How it works — Amazon DynamoDB Developer Guide
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
最後核實於 2026-07-13,依據上方連結的 AWS 官方文件。