I'm in the process of moving my ndb codebase to async as much as possible where it makes sense. There is a scenario where I'm not quite sure how to proceed: transactions.
As I see it, I have 3 options available:
Option 1: Call ndb.transaction()
synchronously, and have the transaction's function call async methods.
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)
Option 2: Call ndb.transaction()
asynchronously, and have the transaction's function call sync methods.
@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
Option 3: Call ndb.transaction()
asynchronously, and have the transaction's function call async methods.
@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
I feel like option 3 is the one to go to, but I'd rather rely on an expert opinion/advice...