Ошибка в транзакции NDB? - PullRequest
       15

Ошибка в транзакции NDB?

2 голосов
/ 16 апреля 2019

Я использовал фрагмент кода, подобный тому, что я скопировал ниже в течение пары лет.

Основная идея заключается в том, что 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 сущностей выполняются в транзакциях.

Почему-то у меня теперь есть личность, которая дважды состоит в браке (часть двух Брачных сущностей)! Впервые за последние годы это произошло, но это смущает, что это может произойти.

Есть ли ошибка в моем коде? Если нет, есть идеи, как это произошло?

1 Ответ

1 голос
/ 16 апреля 2019

оба брака были созданы одновременно?

У меня были странные проблемы с устаревшим кэшем, возможно, внесите это изменение: 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, чтобы снова быть ложным)
...