Hello,

Like its predecessors `commit_on_success` and `xact`, `transaction.atomic` 
doesn't guarantee atomicity if the connection gets closed in the middle of the 
transaction. Django automatically reopens it and proceeds happily, losing the 
first half of the transaction and saving only the second half.

I just submitted a pull request to fix this problem: 
https://github.com/django/django/pull/2468. Since it isn't trivial,, I would 
like a serious review before I push it.

The easy case is when the connection is closed on the client side by 
application code. It's a stupid thing to do, but since atomic pretends to be 
robust, we have to handle that case.

The hard case is when the connection is closed on the server side or lost for 
whatever reason. In that situation Django doesn't get notified. \soon as Django 
tries to commit or rollback the transaction -- and one of these is going to 
happen before exiting atomic -- it's going to receive an exception. If commit 
raises an exception, Django tries to rollback. If rollback raises an exception, 
it means that the connection is dead. To the best of my knowledge, there's no 
other situation where rollback can fail. So, all Django needs to do is close 
the connection when rollback fails, and we're back to the easy case.

If you've encountered problems with dead connections before, I love to hear 
your feedback on this PR. It's written against master but it should apply to 
1.7 and 1.6 with few changes, if any.

Thank you,

-- 
Aymeric.



-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/E563B049-53FA-443A-9461-43C36A825FE0%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to