ndb.transaction_async()与事务内的异步调用

时间:2013-02-12 03:10:25

标签: google-app-engine app-engine-ndb

我正在将我的ndb代码库尽可能多地移动到异步中。有一种情况我不太清楚如何继续:交易。

在我看来,我有3种选择:

选项1:同步调用ndb.transaction(),并使事务的函数调用异步方法。

def option_1():
    @ndb.tasklet
    def txn():
        e = yield Foo.get_by_id_async(some_id)
        if e is None:
            e = yield Foo().put_async()
        raise ndb.Return(e)

    # The doc for ndb.transaction() says that it takes a function or tasklet.
    # If it's a tasklet, does it wait on the Future that is returned?
    # If it doesn't wait, what is the proper way to call a tasklet in a transaction
    # and get access to its return value?
    return ndb.transaction(txn)

选项2:异步调用ndb.transaction(),并使用事务的函数调用同步方法。

@ndb.toplevel
def option_2():
    def txn():
        e = Foo.get_by_id(some_id)
        if e is None:
            e = Foo().put()
        return e

    result = yield ndb.transaction_async(txn)
    return result

选项3:异步调用ndb.transaction(),并使事务的函数调用异步方法。

@ndb.toplevel
def option_3():
    @ndb.tasklet
    def txn():
        e = yield Foo.get_by_id_async(some_id)
        if e is None:
            e = yield Foo().put_async()
        raise ndb.Return(e)

    result = yield ndb.transaction_async(txn)
    return result

我觉得选项3是可以选择的,但我宁愿依赖专家意见/建议......

1 个答案:

答案 0 :(得分:9)

是的,#3绝对是要走的路。另外两个问题是它们混合了异步和同步代码,除了应用程序的最顶层外,这通常不是一件好事。

PS。实际上,如果事务是一个tasklet,事务会等待回调。