Reputation: 489
I have two tasks (a
, b
) those should be performed in transaction in order avoid inconsistency. I may need to perform one of the tasks or both of them together.
In below code function_a
performs task a
and function_b
performs task b
.
@ndb.transactional
def function_a():
# basic validations
# read entity of type A
# make changes to entity
# write entity
return
@ndb.transactional
def function_b():
# basic validations
# read entity of type B
# make changes to entity
# write entity
return
So if I need to perform task a and b together. I can perform as below :-
def function_ab():
function_a()
function_b()
return
but this implementation will not maintain consistency of A
and B
together, so I need to make it transactional too.
@ndb.transactional
def function_ab():
function_a()
function_b()
return
So, in implementation like this is using transaction multiple times (once on function_ab
and once for individual funcion_a
and function_b
) for the sake of code reusability. If I do not go for code reusability I can do some like below :-
@ndb.transactional
def function_ab():
# basic validations
# read entity of type A
# make changes to entity
# write entity
# basic validations
# read entity of type B
# make changes to entity
# write entity
return
I do not know much about how transactions work in app engine, so my question is, Is there any drawback (performance etc.) of using transactions with code reusability over I do not go for code reusability and does the code reusability approach really work?
Upvotes: 1
Views: 143
Reputation: 39834
You can't nest transactions, your transactional function_ab()
will give an error.
But you can still arrange the code for re-use by ensuring only the top level(s) functions are transactional while the inner ones just check that they are indeed inside a transaction. Maybe something along these lines:
def function_a():
assert ndb.in_transaction()
return
def function_b():
assert ndb.in_transaction()
return
@ndb.transactional
def function_ab(do_a, do_b):
if do_a:
function_a()
if do_b:
function_b()
Your usage pattern is actually textbook fit for using ndb
async tasklets, even more efficient. Look for the get_cart_plus_offers()
example in Tasklets, Parallel Queries, Parallel Yield.
Upvotes: 1