NDB交易中的错误?

时间:2019-04-16 18:04:51

标签: python google-app-engine transactions app-engine-ndb

几年来,我一直在使用与下面复制的代码段相似的代码段。

基本概念是Person可以结婚,当他们结婚时,我创建一个“婚姻”实体。一个人只能结婚一次,因此我有一个布尔值指示该人是否已结婚(Person.married)。一个人结婚后,我将更新Person并在如下交易中创建Marriage实体:

@ndb.transactional(xg=True)
def update_person(pid):
    person = Person.get_by_id(pid)
    if person.married:
        raise RuntimeError("This person is already married.")
    else:
        marriage = Marriage(person=person)
        person.married = True
        ndb.put_multi([person, marriage])

这是我的代码中唯一创建Marriage实体的地方。对Person实体的所有更新都是在交易中完成的。

不知何故,我现在有一个已结婚两次的Person实体(属于两个Marriage实体的一部分)!这是多年以来的第一次,但是令人不安的是,这种情况可能会发生。

我的代码中有错误吗?如果没有,知道这是怎么发生的吗?

1 个答案:

答案 0 :(得分:1)

两个婚姻是同时建立的吗?

我遇到了奇怪的过时缓存问题,也许可以进行以下更改:use_cache=False, use_memcache=False

所以:

person = Person.get_by_id(pid, use_cache=False, use_memcache=False)

https://cloud.google.com/appengine/docs/standard/python/ndb/cache

此外,您所有用于编辑Person的功能都发生在事务中吗?像代码中的其他地方一样,您具有这样的功能:

def update_person_email(pid, email):
    person = Person.get_by_id(pid)
    person.email = email
    person.put()

如果是这样,那么事件的顺序可能是:

  • update_person_email获得Person A
  • 您的update_person得到并投入Person A
  • update_person_email放置Person A(覆盖married再次为假)