DynamoDB TransactionCanceledException — ConditionalCheckFailed
TL;DR — 你的 TransactWriteItems 被取消了,CancellationReasons 数组中有一个 ConditionalCheckFailed 条目。事务的某个条件表达式不成立,因此 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 求值为假,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 的条目标识了其条件表达式求值为假的那个操作;代码为 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 官方文档。