物化交易与常规负载然后保存

时间:2012-12-24 09:05:25

标签: google-app-engine transactions google-cloud-datastore objectify

我只需要确认我做对了。 例如,如果我有一个带有字段X的实体x,并且在发送请求时我想要X.x++。如果我只使用X = ofy().load().type(X.class).id(xId).get(),那么我会进行一些计算,之后我会X.x++并保存它。如果在计算过程中发布了另一个请求,我将收到不需要的行为。相反,如果我在事务中执行此操作,则第二个请求在完成之前将无法访问X

是这样吗?

很抱歉,如果这个问题有点不高兴。

谢谢, 丹

2 个答案:

答案 0 :(得分:2)

是的,你做得对,但是当使用交易记住第一个完成胜利而其余的失败。另请参阅@Peter Knego关于它们如何工作的答案。

但如果第二个请求无法阅读,请不要担心。 你有2个选择:

  1. 强制重试
  2. 在交易中使用最终一致性
  3. 就重试而言:

      

    您可以安全地多次调用您的交易功能   不良副作用。如果无法做到这一点,您可以进行设置   retries = 0,但知道事务将在第一次失败   争用事件

    示例:

    @db.transactional(retries=10)
    

    就最终的一致性而言:

      

    您可以通过指定读取策略来选择不使用此保护   要求最终的一致性。随着最终的一致阅读   一个实体,您的应用获取当前已知的实体状态   阅读,无论是否仍有提交的更改   应用。通过最终一致的祖先查询,索引   用于查询的内容与读取索引的时间一致   从磁盘。换句话说,最终的一致性读取策略会导致   获取和查询的行为就好像它们不是当前的一部分   交易。在某些情况下,这可能会更快,因为操作会这样做   在返回之前不必等待提交的更改   结果。

    示例:

    @db.transactional()
    def test():
        game_version = db.get(
            db.Key.from_path('GameVersion', 1),
            read_policy=db.EVENTUAL_CONSISTENCY)
    

答案 1 :(得分:2)

不,GAE交易不做锁定,他们使用optimistic concurrency control。您将始终可以访问X,但是当您尝试将其保存在第二个交易中时,它将失败并显示ConcurrentModificationException