Django 1.6 and nesting "with transaction.atomic ()"

I use these years for old transactions .commit_on_success and transaction.commit_manual with Django <1.6. But now with Django 1.6, the old API is replaced mainly by the .atomic transaction.

After reading the documents in the new API , I'm still not sure how the following code will be transferred to the database:

def a_first_function(): with transaction.atomic(): a_second_function_successful() a_third_function_fails() def a_second_function_successful(): with transaction.atomic(): do_something() def a_third_function_fails(): do_something_wrong() 

In this example, suppose that a_second_function_successful, called from a_first_function, completes successfully and creates / saves objects from models. Immediately after this second_function succeeds, the third function is called and fails.

Given that transaction.atomic using the context manager is used in the first and second functions, what happens to the data created / modified in a_second_function_successful. Will it be tied to a database? Will it automatically roll back from the first function? My experience is that the second function will be executed independently, however, I expected it to not be executed.

Will it matter now if the third function has been defined as follows:

 @transaction.atomic def a_third_function_fails(): do_something_wrong() 

or how:

 def a_third_function_fails(): with transaction.atomic(): do_something_wrong() 

Thanks,

+7
django django-models transactions django-database
source share
1 answer

Well, I would say that if you have no attempt, except for blocks, to catch the exceptions that trigger the rollback, then everything will be rolled back, since the exception will extend to the top with transaction.atomic() from a_first_function() , even if it rises from a_third_function_fails()

However, if you were to catch the exception in a_third_function_fails , which means you would also need to do something like:

 def a_third_function_fails(): try: with transaction.atomic(): do_something_wrong() except: pass 

Then you will have a third function return, not a second function, because you implicitly create a savepoint when you call with transaction.atomic() from a_third_function_fails .

+5
source share

All Articles