summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2013-09-20 21:56:35 +0200
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-09-20 21:56:35 +0200
commit4db2752e28668ed8826b770ef2ed26e8c1562db6 (patch)
treec61b2ef9ea71320e9c5283ffcfc45d7fc1fb25ca /docs
parent0d1ba84d13eb6000c9f6e54b03d52863fcd31f27 (diff)
Clarified why one must not catch database errors inside atomic.
Diffstat (limited to 'docs')
-rw-r--r--docs/topics/db/transactions.txt14
1 files changed, 14 insertions, 0 deletions
diff --git a/docs/topics/db/transactions.txt b/docs/topics/db/transactions.txt
index 4411b326d7..1483bddd0b 100644
--- a/docs/topics/db/transactions.txt
+++ b/docs/topics/db/transactions.txt
@@ -163,6 +163,20 @@ Django provides a single API to control database transactions.
called, so the exception handler can also operate on the database if
necessary.
+ .. admonition:: Don't catch database exceptions inside ``atomic``!
+
+ If you catch :exc:`~django.db.DatabaseError` or a subclass such as
+ :exc:`~django.db.IntegrityError` inside an ``atomic`` block, you will
+ hide from Django the fact that an error has occurred and that the
+ transaction is broken. At this point, Django's behavior is unspecified
+ and database-dependent. It will usually result in a rollback, which
+ may break your expectations, since you caught the exception.
+
+ The correct way to catch database errors is around an ``atomic`` block
+ as shown above. If necessary, add an extra ``atomic`` block for this
+ purpose -- it's cheap! This pattern is useful to delimit explicitly
+ which operations will be rolled back if an exception occurs.
+
In order to guarantee atomicity, ``atomic`` disables some APIs. Attempting
to commit, roll back, or change the autocommit state of the database
connection within an ``atomic`` block will raise an exception.