Каков наилучший способ сохранить код модульным и отделенным, но избегать ввода транзакции дважды?
У сущностей часто есть методы класса для загрузки, изменения и хранения данных. Часто это должно быть транзакционным, чтобы соответствовать сущностям ребенка / родного брата / двоюродного брата. Вот образец:
class MyEntity(db.Model):
# ... some properties
@classmethod
def update_count(cls, my_key):
def txn():
me = db.get(my_key)
me.count += 23
me.put()
OtherEntity.update_descendants(ancestor=me)
return db.run_in_transaction(txn)
Обычно вы должны извлекать объекты, изменять их и хранить их в одном блоке. Эта техника более эффективна; но иногда производительность менее важна, чем модульность и ремонтопригодность. Два обновления должны быть отделены. (Возможно, update_descendants
часто вызывается изолированно и отвечает за хранение данных.)
Но следующий код является ошибкой:
class OtherEntity(db.Model):
# ... some properties
@classmethod
def update_descendants(cls, ancestor):
def txn(): # XXX Bug!
descendants = cls.all().ancestor(ancestor).fetch(10)
for descendant in descendants:
descendant.update_yourself(ancestor.count)
db.put(descendants)
return db.run_in_transaction(txn)
Возникает исключение:
>>> MyEntity.update_count(my_key=some_key_i_have)
Traceback (most recent call last):
...
BadRequestError: Nested transactions are not supported.
Так, как я могу получить лучшее из обоих миров: модульность и правильность?