DynamoDB TransactionCanceledException — ConditionalCheckFailed
TL;DR — 你的 TransactWriteItems 被取消,且 CancellationReasons 陣列中含有一個 ConditionalCheckFailed 項目。交易的某個 condition expression 未成立,所以 DynamoDB 原子性地回滾了每一個動作。讀取 reasons 陣列 — 其項目依位置排列,每個請求項目一個 — 找出哪個項目的條件失敗,然後修正該項目的前置條件或資料。
這是什麼意思
TransactionCanceledException: Transaction cancelled, please refer cancellation
reasons for specific reasons [ConditionalCheckFailed, None, None]
# CancellationReasons[0] = { Code: "ConditionalCheckFailed",
# Message: "The conditional request failed" }TransactWriteItems 是全有或全無的。若任一動作的 ConditionExpression 求值為 false,DynamoDB 就取消整個請求,並回報一份逐項目的原因列表。位置 i 的 ConditionalCheckFailed 表示第 i 個項目的條件未被滿足 — 交易從未部分套用。
為什麼會發生
- 樂觀鎖未命中 —
version = :v/attribute_not_exists(pk)防護失敗,因為另一個寫入者已經變更或建立了該項目。 - 唯一性防護被觸發 —
attribute_not_exists(pk)插入輸掉了競爭,因此該項目已經存在。 - 過時的讀取 — 條件是根據一個此後已改變的值建立的。
- 原因列表誤讀 — 該陣列是依位置排列的,順序如你的
TransactItems;某個位置的None表示該項目沒問題,ConditionalCheckFailed標記失敗的那一個。(陣列中的其他代碼 —TransactionConflict、ItemCollectionSizeLimitExceeded、ProvisionedThroughputExceeded、ThrottlingError、ValidationError— 意義不同。)
如何修正
- 檢視例外中的
CancellationReasons,找到帶有ConditionalCheckFailed的索引 — 那就是失敗的動作。 - 重新讀取該項目並決定:以新的前置條件重試(樂觀鎖重試迴圈),或向呼叫者浮現衝突。
- 修正條件(若它是錯的)— 例如對一個確實已經存在的項目使用
attribute_not_exists(pk)。 - 對失敗的動作加上
ReturnValuesOnConditionCheckFailure: ALL_OLD,讓 DynamoDB 回傳打破條件的那個項目(很適合除錯)。 - 限制你的重試次數 — 持續失敗的條件是真正的業務衝突,而非暫時性錯誤;不要無限重試。
手動除錯失敗的交易嗎?在 DynoTable 桌面應用程式中檢視目前的項目狀態,在重試前精確看出前置條件為何不成立。
FAQ
我怎麼知道交易中哪個項目失敗了?
讀取 TransactionCanceledException 上的 CancellationReasons 陣列。它是依位置排列的 — 每個請求項目一個項目,依序排列。代碼為 ConditionalCheckFailed 的項目指出其 condition expression 求值為 false 的動作;代碼為 None 的項目成功了。
交易內的 ConditionalCheckFailed 可以重試嗎? 不會自動重試。它是真正的前置條件衝突,而非暫時性錯誤。重新讀取該項目、決定該寫入是否仍適用,並以新的條件重試 — 或向使用者浮現衝突。
相關錯誤
- ConditionalCheckFailedException — 同樣的失敗發生在單一非交易寫入上。
- TransactionCanceledException (overview) — 所有取消原因代碼。
- TransactionConflictException — 同一項目上的並行交易。
- 程式碼範例:TransactWriteItems in Node.js · in Python (boto3) — 可調整的可運作條件交易。
- 學習:DynamoDB transactions · Condition expressions
References
- TransactWriteItems — Amazon DynamoDB API Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
- DynamoDB condition expression examples — Amazon DynamoDB Developer Guide
最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。