Consider this simple example:
(taken from https://code.djangoproject.com/ticket/2227 )
If an exception occurs in Account.add() , the transaction in Account.withdraw() will still be committed and money will be lost, because Django does not currently process nested transactions.
Without applying patches to Django, how can we make sure that the commit is sent to the database, but only when the main function in the @transaction.commit_on_success decor finishes without raising an exception?
I came across this snippet: http://djangosnippets.org/snippets/1343/ , and it looks like he could do the job. Are there any flaws that I should know about if I use them?
Thank you so much in advance if you can help.
PS I copy the previously quoted code snippet for visibility:
def nested_commit_on_success(func): """Like commit_on_success, but doesn't commit existing transactions. This decorator is used to run a function within the scope of a database transaction, committing the transaction on success and rolling it back if an exception occurs. Unlike the standard transaction.commit_on_success decorator, this version first checks whether a transaction is already active. If so then it doesn't perform any commits or rollbacks, leaving that up to whoever is managing the active transaction. """ commit_on_success = transaction.commit_on_success(func) def _nested_commit_on_success(*args, **kwds): if transaction.is_managed(): return func(*args,**kwds) else: return commit_on_success(*args,**kwds) return transaction.wraps(func)(_nested_commit_on_success)
source share