代码之家  ›  专栏  ›  技术社区  ›  vincent

TransactionCanceledException中的神秘TransactionConflict

  •  1
  • vincent  · 技术社区  · 5 年前

    使用 transactWriteItems 在AWS SDK(JS)中,我们得到一个 TransactionCanceledException . 该例外范围内的原因如下: 事务冲突 . 有时事务中的所有操作都会失败,有时只有几个或一个。我们确实并行运行多个事务,可以对相同的项目进行操作。文档没有提到这个特定的错误。可能的原因摘录:

    1. 其中一个条件表达式中的条件不满足。
    2. TransactionWriteItems请求中的表位于其他帐户中,或者 区域。
    3. TransactionWriteItems操作中的多个操作以 同一项目。
    4. 没有足够的已设置容量,事务将 完整的。
    5. 项目大小变得太大(大于400 KB)或本地 二级索引(LSI)太大,或类似的验证错误 由于事务所做的更改而发生。
    6. 存在用户错误,例如数据格式无效。

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

    1 回复  |  直到 5 年前
        1
  •  1
  •   Matthew Pope    5 年前

    你所经历的并不是一个bug,它实际上是功能的一部分,它在 launch announcement .

    事务处理期间未锁定项。dynamodb事务提供可序列化的隔离。如果在事务处理过程中在事务外修改了某个项,则会取消该事务,并引发异常,其中包含导致该异常的一个或多个项的详细信息。

    顺便提一句,dynamodb使用了一种叫做乐观并发控制(optimistic concurrency control)的方法,而不是锁定(locking)。如果你有兴趣了解更多信息,维基百科上的文章 Optimistic Concurrency Control 相当不错。

    回到手头的事情,美国焊接学会 documentation 对于交易来说:

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

    特别是对于transactionwriteitems,他们说:

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

    当正在进行的TransactionWriteItems操作与TransactionWriteItems操作中一个或多个项的并发TransactionWriteItems请求冲突时。在这种情况下,并发请求失败,事务取消异常

    同样,对于TransactGetItems:

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

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