Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine ndb.toplevel和ndb.transactional的交互_Google App Engine_Transactions_Google Cloud Datastore_App Engine Ndb_Google App Engine Python - Fatal编程技术网

Google app engine ndb.toplevel和ndb.transactional的交互

Google app engine ndb.toplevel和ndb.transactional的交互,google-app-engine,transactions,google-cloud-datastore,app-engine-ndb,google-app-engine-python,Google App Engine,Transactions,Google Cloud Datastore,App Engine Ndb,Google App Engine Python,有没有可能让@ndb.toplevel与@ndb.transactional配合得很好 我想要实现的是一个包含entity.put_async()调用的事务,但不必显式地等待未来@ndb.toplevel通常会这样做,但另一个SO问题似乎表明它不能与事务相结合: 我在App Engine文档中的任何地方都找不到明确的文档。我们可以重现该问题中显示的断言错误,但是我们编写了一些测试来查看put\u async()调用是否失败,并且没有看到任何问题。然而,由于有可能丢失数据,因此最好能从熟悉ndb的

有没有可能让
@ndb.toplevel
@ndb.transactional
配合得很好

我想要实现的是一个包含
entity.put_async()
调用的事务,但不必显式地等待未来
@ndb.toplevel
通常会这样做,但另一个SO问题似乎表明它不能与事务相结合:

我在App Engine文档中的任何地方都找不到明确的文档。我们可以重现该问题中显示的断言错误,但是我们编写了一些测试来查看
put\u async()
调用是否失败,并且没有看到任何问题。然而,由于有可能丢失数据,因此最好能从熟悉ndb的人那里得到更具体的答案

下面是我们的简单测试代码。 如果我们同时删除
ndb.toplevel
ndb.transactional
装饰器,测试将失败,正如预期的那样。 但是,如果我们只使用
ndb.transactional
decorator,而不使用
ndb.toplevel
decorator,那么测试就通过了,这是不期望的。这让我担心,
ndb.transactional
中的开销可能刚好足够
put\u async()
调用有足够的时间来完成,但没有任何gaurantee,因此它可能会意外失败

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()

当您仅使用
@ndb.transactional
时,测试通过这一事实是预期的结果:为了确保从不部分应用事务,
@ndb.transactional
等待所有请求完成

因此,范围内(100):test()的代码
等待事务在每次迭代时结束

因此,以下测试通过:

@ndb.transactional(xg=True)
def test():
    for _ in range(10):
        x = AsyncTestModel()
        x.data = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(1000))
        x.put_async()

for x, _ in enumerate(range(100)):
    test()
    assert(AsyncTestModel.query().count() == (x + 1) * 10)

注意:如果您在事务中使用异步查询,您可以查看
@ndb.transactional\u async
(文档)。

当您仅使用
@ndb.transactional
时,测试通过的事实是预期的组件:确保从不部分应用事务,
@ndb.transactional
等待所有请求完成

因此,范围内(100):test()的代码
等待事务在每次迭代时结束

因此,以下测试通过:

@ndb.transactional(xg=True)
def test():
    for _ in range(10):
        x = AsyncTestModel()
        x.data = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(1000))
        x.put_async()

for x, _ in enumerate(range(100)):
    test()
    assert(AsyncTestModel.query().count() == (x + 1) * 10)
注意:如果在事务中使用异步查询,可以查看
@ndb.transactional\u async
(文档)