#10771 closed (fixed)
Add a transaction context manager
| Reported by: | Oliver Beattie | Owned by: | nobody | 
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev | 
| Severity: | Keywords: | transaction, contextmanager | |
| Cc: | Henrique Romano | Triage Stage: | Accepted | 
| Has patch: | yes | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description
For users who use transactions heavily, it is sometimes desirable to be able to wrap parts of a function (but not all of it) in a transaction of its own. Previously, the best way to do this was either to do it manually with a try…except…else block or creating a sub-function wrapped in commit_on_success, but context managers in Python 2.5+ can make this much cleaner by just saying…
with transaction:
    # do stuff
…which will handle committing and rolling back. Attached is a patch that I'd love to see implemented in Django :) The function is extremely similar to commit_on_success (the structure is identical).
Attachments (5)
Change History (15)
by , 17 years ago
| Attachment: | contextmanager.patch added | 
|---|
comment:1 by , 17 years ago
| Triage Stage: | Unreviewed → Design decision needed | 
|---|
comment:2 by , 17 years ago
Seems like something that couldn't be supported until 1.3 at least (or whenever we drop 2.4 support).
comment:3 by , 17 years ago
Actually, defining a context manager does not need the 'with' statement, so it is perfectly possible to add this, providing you only define it is 'contextlib' can be imported (which isn't true for Python < 2.5).  Of course, only people running Python 2.5 or later would be able to make use of this.  There is the problem of writing tests, but these could either be written explicitly using the magic methods __enter__, __exit__ etc., or they could be omitted since this stuff is pretty well covered by the tests for commit_on_success.
comment:4 by , 17 years ago
This can be pretty easily rewritten as you say with __enter__ and __exit__, thereby circumventing the need for contextlib. I'll update the patch.
by , 17 years ago
| Attachment: | contextmanager-v2.patch added | 
|---|
Second patch with support for <Python 2.5
comment:5 by , 17 years ago
I was actually referring to writing the tests by calling __enter__() etc. explicitly, but your change is probably a good idea anyway.  It still is not compatible with Python 2.3, due to decorator syntax, which is trivial to fix.
comment:6 by , 17 years ago
Oh I see. I don't think it would that big of a deal in that regard — it would require some fiddling around when passing errors to __exit__, but it's really a simple case of doing __exit__(*sys.exc_info()), so not that kludgy.
by , 15 years ago
| Attachment: | django-transactions.diff added | 
|---|
comment:7 by , 15 years ago
| milestone: | → 1.3 | 
|---|---|
| Triage Stage: | Design decision needed → Accepted | 
| Version: | 1.0 → SVN | 
comment:8 by , 15 years ago
| Cc: | added | 
|---|
by , 15 years ago
| Attachment: | django-transactions.2.diff added | 
|---|
comment:9 by , 15 years ago
| Resolution: | → fixed | 
|---|---|
| Status: | new → closed | 
Adds a transaction context manager