TransactionCanceledException 中的神秘事务冲突

vin*_*ent 9 transactions amazon-web-services amazon-dynamodb aws-sdk

在 aws-sdk (js) 中使用transactWriteItems我们得到一个TransactionCanceledException。该异常中的原因作为TransactionConflict给出。有时事务中的所有操作都失败,有时只有几个或只有一个。我们确实并行运行多个可以对相同项目进行操作的事务。文档没有提到这个特定的错误。可能的原因摘录:

  1. 不满足条件表达式之一中的条件。
  2. TransactWriteItems 请求中的表位于不同的账户或区域中。
  3. TransactWriteItems 操作中的多个操作针对同一项目。
  4. 没有足够的容量来完成交易。
  5. 项目大小过大(大于400 KB),或本地二级索引(LSI)过大,或因事务更改发生类似验证错误。
  6. 存在用户错误,例如无效的数据格式。

这些都不适用,当重试事务时,它似乎最终有效。有人知道这个例外吗?我找不到任何文件记录。

Mat*_*ope 20

您遇到的不是错误——它实际上是功能的一部分,并且在发布公告中提到过。

交易期间不会锁定项目。DynamoDB 事务提供可序列化的隔离。如果在事务进行期间在事务之外修改了某个项目,则该事务将被取消并引发异常,其中包含有关哪个或哪些项目导致异常的详细信息。

顺便说一句,DynamoDB 使用一种称为乐观并发控制(这也(令人困惑地)称为乐观锁定)的东西,而不是锁定。如果您有兴趣了解更多相关信息,Wikipedia 上关于Optimistic Concurrency Control 的文章非常好。

回到手头的问题,AWS交易文档说:

同时更新相同项目的多个事务可能会导致取消事务的冲突。我们建议遵循 DynamoDB 数据建模最佳实践,以尽量减少此类冲突。

专门针对 TransactWriteItems,他们说:

在以下情况下写事务不会成功:

当正在进行的 TransactWriteItems 操作与对 TransactWriteItems 操作中的一个或多个项目的并发 TransactWriteItems 请求冲突时。在这种情况下,并发请求失败并出现 TransactionCancelledException

同样对于 TransactGetItems:

在以下情况下读取事务不会成功:

当正在进行的 TransactGetItems 操作与并发 PutItem、UpdateItem、DeleteItem 或 TransactWriteItems 请求冲突时。在这种情况下,TransactGetItems 操作失败并出现 TransactionCancelledException

  • 这很烦人..我希望 Dynamo 将请求排入同一项目而不是抛出错误..我有一个投票应用程序,我在其中不断更新投票数量,例如“ADD upVotes = upVotes + 1”,然后我开始在负载测试时看到很多此类事务取消错误...刚刚引入了一些具有指数退避的重试,让我们看看这是否有帮助... (3认同)
  • 非常感谢。当我扫描文档时,我完全错过了这一点。至少下一个遇到错误的人现在将这张票作为参考!干杯! (2认同)