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.