Transaction committed on user abort
|Reported by:||George Lund||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||1.3|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
If the user aborts execution of some code (e.g. with Control+C), any ongoing transaction is committed, rather than rolled back. This is in Python 2.5, I suspect later versions could be different.
from __future__ import with_statement from django.db import transaction with transaction.commit_on_success(): for x in xx: # long loop
If an "normal" exception is raised during the long loop, the transaction aborts correctly.
However, if the user presses Control+C (very possible during a management command), the half-finished transaction is committed.
The reason is that the Transaction's __exit__ method only passes on exc_value, but not exc_type.
At least in Python 2.5, exc_type can be set, whilst exc_value is still None.
(Pdb) exc_type <type 'exceptions.KeyboardInterrupt'> (Pdb) exc_value (Pdb) exc_value is None True
This is really confusing, and I'd certainly hope it got fixed in a later version of Python.
From a brief look at the code it looks like rather than pass on exc_value to the
exiting function, we could just pass on a Boolean success flag, based on whether any of the three
__exit__ parameters were set. I'll try and work up a patch today.