我想知道 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)
答案 0 :(得分:4)
这是一种安全的方法。如果同一名称生成两次,则只会创建一个实体。
听起来您已经查看了transactions文档。还有一个detailed description。
查看Model.get_or_insert
上的文档(特别是等效代码),它完全回答了您提出的问题:
获取和后续(可能)放置 被包装在交易中以确保 原子。这意味着 get_or_insert()永远不会覆盖 现有实体,并将插入一个 当且仅当没有实体时,新实体 具有给定的种类和名称。
答案 1 :(得分:0)
你所做的是正确的,并且像罗伯特已经解释过的那样重复Model.get_or_insert。
我不知道这是否可以被称为'锁'......这种方式的工作方式是optimistic concurrency - 操作将在假设没有其他人试图同时做同样的事情的情况下执行时间,如果有人,它会给你一个例外。在这种情况下,您需要弄清楚您想要做什么。也许要求用户选择一个新名称?