@@ -6,41 +6,45 @@ Transactions
66
77.. module :: django_mongodb_backend.transaction
88
9- MongoDB supports :doc: `transactions <manual:core/transactions >` if it's configured as a
10- :doc: `replica set <manual:replication >` or a :doc: `sharded cluster <manual:sharding >`.
9+ MongoDB supports :doc: `transactions <manual:core/transactions >` if it's
10+ configured as a :doc: `replica set <manual:replication >` or a :doc: `sharded
11+ cluster <manual:sharding>`.
1112
12- Because MongoDB transactions have some limitations and are not meant to be used as
13- freely as SQL transactions, :doc: `Django's transactions APIs
13+ Because MongoDB transactions have some limitations and are not meant to be used
14+ as freely as SQL transactions, :doc: `Django's transactions APIs
1415<django:topics/db/transactions>`, including most notably
1516:func: `django.db.transaction.atomic `, function as no-ops.
1617
1718Instead, Django MongoDB Backend provides its own
1819:func: `django_mongodb_backend.transaction.atomic ` function.
1920
20- Outside of a transaction, query execution uses Django and MongoDB's default behavior of
21- autocommit mode. Each query is immediately committed to the database.
21+ Outside of a transaction, query execution uses Django and MongoDB's default
22+ behavior of autocommit mode. Each query is immediately committed to the
23+ database.
2224
2325Controlling transactions
2426========================
2527
2628.. function :: atomic(using=None)
2729
28- Atomicity is the defining property of database transactions. ``atomic `` allows
29- creating a block of code within which the atomicity on the database is guaranteed.
30- If the block of code is successfully completed, the changes are committed to the
31- database. If there is an exception, the changes are rolled back.
30+ Atomicity is the defining property of database transactions. ``atomic ``
31+ allows creating a block of code within which the atomicity on the database
32+ is guaranteed. If the block of code is successfully completed, the changes
33+ are committed to the database. If there is an exception, the changes are
34+ rolled back.
3235
33- On databases that support savepoints, ``atomic `` blocks can be nested, such that
34- the outermost ``atomic `` starts a transaction and inner ``atomic ``\s create
35- savepoints. Since MongoDB doesn't support savepoints, inner ``atomic `` blocks
36- don't have any effect. The transaction commits once the outermost ``atomic `` exits.
36+ On databases that support savepoints, ``atomic `` blocks can be nested, such
37+ that the outermost ``atomic `` starts a transaction and inner ``atomic ``\s
38+ create savepoints. Since MongoDB doesn't support savepoints, inner
39+ ``atomic `` blocks don't have any effect. The transaction commits once the
40+ outermost ``atomic `` exits.
3741
3842 ``atomic `` is usable both as a :py:term: `decorator `::
3943
4044 from django_mongodb_backend import transaction
4145
4246
43- @atomic
47+ @transaction. atomic
4448 def viewfunc(request):
4549 # This code executes inside a transaction.
4650 do_stuff()
@@ -54,31 +58,32 @@ Controlling transactions
5458 # This code executes in autocommit mode (Django's default).
5559 do_stuff()
5660
57- with atomic():
61+ with transaction. atomic():
5862 # This code executes inside a transaction.
5963 do_more_stuff()
6064
6165 .. admonition :: Avoid catching exceptions inside ``atomic``!
6266
63- When exiting an ``atomic `` block, Django looks at whether it's exited normally
64- or with an exception to determine whether to commit or roll back. If you catch
65- and handle exceptions inside an ``atomic `` block, you may hide from Django the
66- fact that a problem has happened. This can result in unexpected behavior.
67+ When exiting an ``atomic `` block, Django looks at whether it's exited
68+ normally or with an exception to determine whether to commit or roll
69+ back. If you catch and handle exceptions inside an ``atomic `` block,
70+ you may hide from Django the fact that a problem has happened. This can
71+ result in unexpected behavior.
6772
68- This is mostly a concern for :exc: `~django.db.DatabaseError ` and its subclasses
69- such as :exc: `~django.db.IntegrityError `. After such an error, the transaction
70- is broken and Django will perform a rollback at the end of the `` atomic ``
71- block.
73+ This is mostly a concern for :exc: `~django.db.DatabaseError ` and its
74+ subclasses such as :exc: `~django.db.IntegrityError `. After such an
75+ error, the transaction is broken and Django will perform a rollback at
76+ the end of the `` atomic `` block.
7277
7378 .. admonition :: You may need to manually revert app state when rolling back a transaction.
7479
75- The values of a model's fields won't be reverted when a transaction rollback
76- happens. This could lead to an inconsistent model state unless you manually
77- restore the original field values.
80+ The values of a model's fields won't be reverted when a transaction
81+ rollback happens. This could lead to an inconsistent model state unless
82+ you manually restore the original field values.
7883
79- For example, given ``MyModel `` with an ``active `` field, this snippet ensures
80- that the ``if obj.active `` check at the end uses the correct value if updating
81- ``active `` to ``True `` fails in the transaction::
84+ For example, given ``MyModel `` with an ``active `` field, this snippet
85+ ensures that the ``if obj.active `` check at the end uses the correct
86+ value if updating ``active `` to ``True `` fails in the transaction::
8287
8388 from django_mongodb_backend import transaction
8489 from django.db import DatabaseError
@@ -94,11 +99,12 @@ Controlling transactions
9499 if obj.active:
95100 ...
96101
97- This also applies to any other mechanism that may hold app state, such as
98- caching or global variables. For example, if the code proactively updates data
99- in the cache after saving an object, it's recommended to use
100- :ref: `transaction.on_commit() <performing-actions-after-commit >` instead, to
101- defer cache alterations until the transaction is actually committed.
102+ This also applies to any other mechanism that may hold app state, such
103+ as caching or global variables. For example, if the code proactively
104+ updates data in the cache after saving an object, it's recommended to
105+ use :ref: `transaction.on_commit() <performing-actions-after-commit >`
106+ instead, to defer cache alterations until the transaction is actually
107+ committed.
102108
103109 ``atomic `` takes a ``using `` argument which should be the name of a
104110 database. If this argument isn't provided, Django uses the ``"default" ``
@@ -111,17 +117,27 @@ Controlling transactions
111117
112118.. admonition :: Performance considerations
113119
114- Open transactions have a performance cost for your database server. To minimize
115- this overhead, keep your transactions as short as possible. This is especially
116- important if you're using :func: `atomic ` in long-running processes, outside of
117- Django's request / response cycle.
120+ Open transactions have a performance cost for your database server. To
121+ minimize this overhead, keep your transactions as short as possible. This
122+ is especially important if you're using :func: `atomic ` in long-running
123+ processes, outside of Django's request / response cycle.
118124
119125Performing actions after commit
120126===============================
121127
122- The :func: `atomic ` function supports Django's :func: `~django.db.transaction.on_commit `
123- API to :ref: `perform actions after a transaction successfully commits
124- <performing-actions-after-commit>`.
128+ The :func: `atomic ` function supports Django's
129+ :func: `~django.db.transaction.on_commit ` API to :ref: `perform actions after a
130+ transaction successfully commits <performing-actions-after-commit>`.
131+
132+ For convenience, :func: `~django.db.transaction.on_commit ` is aliased at
133+ ``django_mongodb_backend.transaction.on_commit `` so you can use both::
134+
135+ from django_mongodb_backend import transaction
136+
137+
138+ transaction.atomic()
139+ transaction.on_commit(...)
140+
125141
126142.. _transactions-limitations :
127143
@@ -132,17 +148,7 @@ MongoDB's transaction limitations that are applicable to Django are:
132148
133149- :meth: `QuerySet.union() <django.db.models.query.QuerySet.union> ` is not
134150 supported inside a transaction.
135- - If a transaction raises an exception, the transaction is no longer usable.
136- For example, if the update stage of :meth: `QuerySet.update_or_create()
137- <django.db.models.query.QuerySet.update_or_create> ` fails with
138- :class: `~django.db.IntegrityError ` due to a unique constraint violation, the
139- create stage won't be able to proceed.
140- :class: `pymongo.errors.OperationFailure ` is raised, wrapped by
141- :class: `django.db.DatabaseError `.
142151- Savepoints (i.e. nested :func: `~django.db.transaction.atomic ` blocks) aren't
143152 supported. The outermost :func: `~django.db.transaction.atomic ` will start
144153 a transaction while any subsequent :func: `~django.db.transaction.atomic `
145154 blocks will have no effect.
146- - Migration operations aren't :ref: `wrapped in a transaction
147- <topics/migrations:transactions>` because of MongoDB restrictions such as
148- adding indexes to existing collections while in a transaction.
0 commit comments