【问题标题】:gql inside transactionsgql 内部交易
【发布时间】:2012-05-18 09:09:03
【问题描述】:

Google 应用引擎返回“BadRequestError:事务中只允许祖先查询”。这在代码上下文中意味着什么:

class Counter(db.Model):
        totalRegistrations = db.IntegerProperty(default=0)   

@db.transactional
def countUsers():
    counter = Counter.all().get()
    counter.totalRegistrations = counter.totalRegistrations + 1
    counter.put()
    i = counter.totalRegistrations
    return i

print countUsers()

【问题讨论】:

  • 请注意,您所做的是一种反模式:通过拥有一个需要更新的实体,您将此代码的调用者限制为大约 1QPS。此外,您应该首先使用键名来避免查询的需要。此外,永远,永远不要在 web 应用程序中使用 print
  • 嗨尼克,感谢您的评论。您能否解释一下“使用键名来避免查询的需要”是什么意思。我知道这段代码会造成 GAE 瓶颈,但您是如何提出 1QPS 限制的?谢谢。
  • 如果你只有一个计数器,你可以在创建时指定一个键名。然后,使用您指定的名称在事务中使用Counter.get_by_key_name,避免查询。 1QPS 限制是记录在案的事务数下限,您可以期望能够在单个实体组上执行。在您的应用中引入这种瓶颈是一个非常糟糕的主意。

标签: python google-app-engine


【解决方案1】:

这只是意味着您使用Counter.all().get() 运行的查询不是祖先查询。在这种情况下,您应该从事务方法中获取获取计数器的查询,如下所示:

@db.transactional
def incrementUsers(counterKey):
    counter = Counter.get(counterKey)
    counter.totalRegistrations = counter.totalRegistrations + 1
    counter.put()
    return counter.totalRegistrations

counterKey = Counter.all(keys_only=True).get()

print incrementUsers(counterKey)

这意味着你首先得到一个对 Counter 的引用,但只在事务方法中获取和放入值,保证原子性。

【讨论】:

    猜你喜欢
    • 2021-10-04
    • 2018-06-12
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多