Reputation: 10477
Let's say I have a view function foo
that calls model method bar
. Both foo
and bar
are decorated with @method_decorator(transaction.commit_manually)
. Both always do a transaction.rollback()
before returning.
Will this nested rollback work as intended, i.e. that no database changes happen when foo
is called?
(From my testing, it seems to work, but I'm uncertain as I couldn't find anything definitive about Django transactions that applied to this case. Note I'm using Django 1.4 with PostgreSQL 9.1.4.)
Upvotes: 3
Views: 896
Reputation: 1478
You must be careful here, the DB commit/rollback is connection level, if You have something like this:
@transaction.commit_manually
def foo():
bar()
transaction.rollback()
@transaction.commit_manually
def bar()
#some db op
transaction.commit()
#running
foo()
changes to the database will be commited, You should put @transaction.commit_manually on top level functions. In django 1.6 transaction.atomic decorator was introduced which generally provides what you are looking for:
atomic blocks can be nested. In this case, when an inner block completes successfully, its effects can still be rolled back if an exception is raised in the outer block at a later point
On the other hand You just make rollbacks it should be OK (if you want to stick to 1.4), as long as the commit is on the top level only, but it's best to keep the transaction management on one level in this case (for example raising Exceptions and handling them in foo())
Upvotes: 4