有没有可能@ndb.toplevel
玩得很好@ndb.transactional
?
我想要实现的是一个包含entity.put_async()
调用的事务,但方便的是不必显式等待期货。@ndb.toplevel
通常会这样做,但另一个 SO 问题似乎表明它不能与事务结合使用:“ndb 顶级中断事务吗?”
我在 App Engine 文档的任何地方都找不到明确记录的内容。我们可以重现该问题中显示的断言错误,但我们编写了一些测试来查看put_async()
调用是否失败并且没有发现任何问题。但是,由于可能会丢失数据,因此很高兴在这里从熟悉 ndb 的人那里获得更具体的答案。
我们的简单测试代码如下。如果我们同时删除 thendb.toplevel
和ndb.transactional
装饰器,测试将失败,正如预期的那样。但是,如果我们只使用ndb.transactional
装饰器而忽略ndb.toplevel
装饰器,则测试通过,这是意料之中的。这让我担心,也许ndb.transactional
调用put_async()
有足够的时间来完成,但没有任何保证,所以它可能会意外失败?
class AsyncTestModel(ndb.Model):
data = ndb.StringProperty(indexed=True)
@ndb.toplevel
def start_test():
for _ in range(100):
test()
# Check we wrote all the entities
time.sleep(30)
entities = AsyncTestModel.query().fetch()
assert(len(entities) == 1000)
@ndb.transactional(xg=True)
def test():
for _ in range(10):
x = AsyncTestModel()
x.data = make_random_string(1000)
x.put_async()