I am using Google App Engine SDK 1.7.3 and NDB to access the datastore.
How should I run a non-transactional tasklet from within a transactional tasklet?
The following is the first thing that comes to mind:
@ndb.tasklet
@ndb.non_transactional
def non_txn_method():
''' Run some code that does not require a transaction '''
result = calculate_result()
raise ndb.Return(result)
@ndb.tasklet
@ndb.transactional
def txn_method():
''' Run some code that requires a transaction '''
non_txn_result = yield non_txn_method()
However the creator of NDB advises not to combine decorators such as is done with @ndb.tasklet and @ndb.transactional and to use the ndb.transaction_async(callback, **ctx_options) function instead. See here for the issue with doing this. I am therefore worried that combining the @ndb.tasklet and @ndb.non_transactional decorators could also be fragile and prone to have unexpected behaviour.
Note that ndb.transaction_async(callback, **ctx_options) is provided in the NDB API but not ndb.non_transaction_async(callback, **ctx_options).
I wonder if a ndb.non_transaction_async(callback, **ctx_options) function needs to be exposed in the NDB API to help me robustly accomplish what I want to do?
I recommend that you file a bug for the proposed new feature in the NDB bug tracker:
http://code.google.com/p/appengine-ndb-experiment/issues/list