【问题标题】:Concurent Access to datastore in app engine并发访问应用引擎中的数据存储
【发布时间】:2010-12-01 06:44:35
【问题描述】:

我想知道 db.run_in_transaction() 是否充当数据存储操作的 并在同一实体上并发访问时提供帮助。

在下面的代码中是否保证并发访问不会导致竞争,而不是创建新实体,它不会进行覆盖

db.run_in_transaction() 是否正确/最好的方法

在下面的代码中,我试图用下面的代码创建新的唯一实体

def txn(charmer=None):
    new = None
    key = my_magic() + random_part()
    sk = Snake.get_by_name(key)
    if not sk:
       new = Snake(key_name=key, charmer= charmer)
       new.put()
    return new
db.run_in_transaction(txn, charmer) 

【问题讨论】:

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


    【解决方案1】:

    这是一种安全的方法。如果同一名称生成两次,则只会创建一个实体。

    听起来您已经看过transactions 文档。还有一个detailed description

    查看Model.get_or_insert 上的文档(特别是等效代码),它准确地回答了您提出的问题:

    get 和随后的(可能的)put 被包裹在一个事务中以确保 原子性。这意味着 get_or_insert() 永远不会覆盖 一个现有的实体,并将插入一个 新实体当且仅当没有实体 具有给定种类和名称的存在。

    【讨论】:

    • 非常感谢 Robert Kluin 的帮助......我想使用它 Model.get_or_insert 但想知道如何确保返回的实体是新创建的或现有的。我应该将返回实体的属性与我想要放置的属性进行比较。
    • 您可以使用您的代码,也可以比较属性。假设在不同时间创建的两个实体也不具有相同的属性,或者您不关心它们是否具有。
    【解决方案2】:

    您所做的是正确的,并且有点重复 Model.get_or_insert,就像 Robert 已经解释的那样。

    我不知道这是否可以称为“锁定”...它的工作方式是optimistic concurrency - 假设没有其他人同时尝试做同样的事情,该操作将执行,如果有人是,它会给你一个例外。你需要弄清楚在这种情况下你想做什么。也许要求用户选择一个新名称?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 2017-05-02
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多