gpt4 book ai didi

python - 以事务方式或非事务方式修改实体数据(取决于需要)

转载 作者:太空宇宙 更新时间:2023-11-04 01:43:35 25 4
gpt4 key购买 nike

保持代码模块化和解耦但避免两次输入事务的最佳方法是什么?

实体通常有类方法来加载、修改和存储数据。通常,这必须是事务性的才能与 child / sibling /堂兄弟实体保持一致。这是模式:

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)

通常,您应该获取实体、修改它们并将它们存储在一次 block 中。该技术性能更高;但有时性能不如模块化和可维护性重要。这两个更新应该是分离的。 (也许 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.

那么我怎样才能兼顾模块化和正确性呢?

最佳答案

我使用的模式是有一个参数指示是否需要事务行为。

class OtherEntity(db.Model):
# ... some properties

@classmethod
def update_descendants(cls, ancestor, with_transaction=True):
if with_transaction:
return db.run_in_transaction(cls.update_descendants, ancestor,
with_transaction=False)

# Now I can assume I am in a transaction one way or another...
descendants = cls.all().ancestor(ancestor).fetch(10)
for descendant in descendants:
descendant.update_yourself(ancestor.count)
return db.put(descendants)

可以扩展相同的原则以指示是对 put 负责,还是将其留给调用者。

关于python - 以事务方式或非事务方式修改实体数据(取决于需要),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2257946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com