gpt4 book ai didi

google-app-engine - 如果最近的事务引发 "special"异常,事务性 db.get() 是否可能返回过时的结果?

转载 作者:太空宇宙 更新时间:2023-11-03 15:23:13 25 4
gpt4 key购买 nike

这是在应用程序引擎中 transaction docs ...

Note: If your application receives an exception when committing a transaction, it does not always mean that the transaction failed. You can receive Timeout, TransactionFailedError, or InternalError exceptions in cases where transactions have been committed and eventually will be applied successfully...

考虑以下场景

  1. 我在事务中更新实体 A
  2. 事务操作导致上述特殊“异常”,其中事务已提交并最终将被应用
  3. 我在另一个事务中运行 db.get(entity_a_key_goes_here) 紧接着,或者几乎与第 2 步同时运行。
  4. 如果上面的第 3 步返回 None,我通过将键设置为 entity_a_key_goes_heredb.put() 来创建该实体(步骤3 和此步骤在同一事务中运行)。

我的问题:

上面步骤 3 中的事务性 db.get() 操作是否有可能返回过时值(或者不是步骤 1 中设置的更新值) ?事务性 db.get() 操作是否保证返回最新的结果,即使“奇怪的”事务异常就在它之前发生?

最佳答案

get 并不是真正的“事务性”;如果事务只包含读取,那么提交事务实际上并没有做任何事情。在事务中执行读取只保证一件事:如果在事务中应用任何写入时,读取返回的值不再是最新值,事务将中止并且没有的写入将发生。

因此,允许发生以下事件序列:

  1. 开始事务 1。
  2. 在事务 1 中,您读取实体 A 并返回状态 A1。
  3. 在事务 1 中,您将实体 A 从状态 A1 更新为状态 A2。
  4. 提交事务 1 时,它因上述异常之一而失败。
  5. 开始事务 2。
  6. 在事务 2 中,您读取实体 A 并返回状态 A1。
  7. 事务 1 在后台应用于数据存储,将 A 从状态 A1 更改为状态 A2。
  8. 结束事务 2(没有提交,因为没有写入)。

但是,这一系列事件是不同的:

  1. 开始事务 1。
  2. 在事务 1 中,您读取实体 A 并返回状态 A1。
  3. 在事务 1 中,您将实体 A 从状态 A1 更新为状态 A2。
  4. 提交事务 1 时,它因上述异常之一而失败。
  5. 开始事务 2。
  6. 在事务 2 中,您读取实体 A 并返回状态 A1。
  7. 在事务 2 中,您将实体 A 从状态 A1 更新为状态 A3。
  8. 事务 1 在后台应用于数据存储,将 A 从状态 A1 更改为状态 A2。
  9. 事务 2 现在不会成功提交,因为它即将应用的写入是基于实体 A 的过时版本。它将失败并且 A 将留在状态 A2。

因此,将第 4 步添加到问题后,您处于此处的第二个事件序列中。即使实体确实存在,步骤 3 中的 get 也可能返回 None,但在这种情况下后续写入不可能成功:事务已过期,因此无法提交。事务将被重试,第二次,get 将返回在步骤 1 中写入的对象,这就是您想要的。

所以非常简短的回答是:是的,它可以返回一个陈旧的值,但它保证如果结果是陈旧的,在同一事务中对该实体的后续写入将失败,所以这实际上应该不会造成问题。

关于google-app-engine - 如果最近的事务引发 "special"异常,事务性 db.get() 是否可能返回过时的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16998682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com