@@ -4,100 +4,87 @@ Transactions
44
55.. versionadded :: 5.2.0b2
66
7- .. module :: django_mongod_backend .transaction
7+ .. module :: django_mongodb_backend .transaction
88
99MongoDB supports :doc: `transactions <manual:core/transactions >` if it's configured as a
1010:doc: `replica set <manual:replication >` or a :doc: `sharded cluster <manual:sharding >`.
1111
12- Because MongoDB transactions have some differences compared to SQL transactions,
13- :doc: `Django's transactions APIs <django:topics/db/transactions >` function as no-ops.
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
14+ <django:topics/db/transactions>`, including most notably
15+ :func: `django.db.transaction.atomic `, function as no-ops.
1416
15- Instead, Django MongoDB Backend provides its own `` atomic() `` function, similar to
16- Django's :func: `django.db. transaction.atomic `.
17+ Instead, Django MongoDB Backend provides its own
18+ :func: `django_mongodb_backend. transaction.atomic ` function .
1719
1820Outside of a transaction, query execution uses Django and MongoDB's default behavior of
1921autocommit mode. Each query is immediately committed to the database.
2022
2123Controlling transactions
22- ------------------------
24+ ========================
2325
2426.. function :: atomic(using=None, durable=False)
2527
26- Atomicity is the defining property of database transactions. ``atomic ``
27- allows us to create a block of code within which the atomicity on the
28- database is guaranteed. If the block of code is successfully completed, the
29- changes are committed to the database. If there is an exception, the
30- changes are rolled back.
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.
3132
32- ``atomic `` blocks can be nested. In this case, when an inner block
33- completes successfully, its effects can still be rolled back if an
34- exception is raised in the outer block at a later point.
35-
36- It is sometimes useful to ensure an ``atomic `` block is always the
37- outermost ``atomic `` block, ensuring that any database changes are
38- committed when the block is exited without errors. This is known as
39- durability and can be achieved by setting ``durable=True ``. If the
40- ``atomic `` block is nested within another it raises a ``RuntimeError ``.
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.
4137
4238 ``atomic `` is usable both as a :py:term: `decorator `::
4339
44- from django.db import transaction
40+ from django_mongodb_backend import transaction
4541
4642
47- @transaction. atomic
43+ @atomic
4844 def viewfunc(request):
4945 # This code executes inside a transaction.
5046 do_stuff()
5147
5248 and as a :py:term: `context manager `::
5349
54- from django.db import transaction
50+ from django_mongodb_backend import transaction
5551
5652
5753 def viewfunc(request):
5854 # This code executes in autocommit mode (Django's default).
5955 do_stuff()
6056
61- with transaction. atomic():
57+ with atomic():
6258 # This code executes inside a transaction.
6359 do_more_stuff()
6460
6561 .. admonition :: Avoid catching exceptions inside ``atomic``!
6662
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
71- can result in unexpected behavior.
72-
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. If you attempt to run database
77- queries before the rollback happens, Django will raise a
78- :class: `~django.db.transaction.TransactionManagementError `. You may
79- also encounter this behavior when an ORM-related signal handler raises
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+
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. If you attempt to run database queries before the rollback happens,
72+ Django will raise a :class: `~django.db.transaction.TransactionManagementError `.
73+ You may also encounter this behavior when an ORM-related signal handler raises
8074 an exception.
8175
82- The correct way to catch database errors is around an ``atomic `` block
83- as shown above. If necessary, add an extra ``atomic `` block for this
84- purpose. This pattern has another advantage: it delimits explicitly
85- which operations will be rolled back if an exception occurs.
86-
87- If you catch exceptions raised by raw SQL queries, Django's behavior
88- is unspecified and database-dependent.
89-
9076 .. admonition :: You may need to manually revert app state when rolling back a transaction.
9177
92- The values of a model's fields won't be reverted when a transaction
93- rollback happens. This could lead to an inconsistent model state unless
94- you manually restore the original field values.
78+ The values of a model's fields won't be reverted when a transaction rollback
79+ happens. This could lead to an inconsistent model state unless you manually
80+ restore the original field values.
9581
96- For example, given ``MyModel `` with an ``active `` field, this snippet
97- ensures that the ``if obj.active `` check at the end uses the correct
98- value if updating ``active `` to ``True `` fails in the transaction::
82+ For example, given ``MyModel `` with an ``active `` field, this snippet ensures
83+ that the ``if obj.active `` check at the end uses the correct value if updating
84+ ``active `` to ``True `` fails in the transaction::
9985
100- from django.db import DatabaseError, transaction
86+ from django_mongodb_backend import transaction
87+ from django.db import DatabaseError
10188
10289 obj = MyModel(active=False)
10390 obj.active = True
@@ -110,37 +97,39 @@ Controlling transactions
11097 if obj.active:
11198 ...
11299
113- This also applies to any other mechanism that may hold app state, such
114- as caching or global variables. For example, if the code proactively
115- updates data in the cache after saving an object, it's recommended to
116- use :ref: `transaction.on_commit() <performing-actions-after-commit >`
117- instead, to defer cache alterations until the transaction is actually
118- committed.
119-
120- In order to guarantee atomicity, ``atomic `` disables some APIs. Attempting
121- to commit, roll back, or change the autocommit state of the database
122- connection within an ``atomic `` block will raise an exception.
100+ This also applies to any other mechanism that may hold app state, such as
101+ caching or global variables. For example, if the code proactively updates data
102+ in the cache after saving an object, it's recommended to use
103+ :ref: `transaction.on_commit() <performing-actions-after-commit >` instead, to
104+ defer cache alterations until the transaction is actually committed.
123105
124106 ``atomic `` takes a ``using `` argument which should be the name of a
125107 database. If this argument isn't provided, Django uses the ``"default" ``
126108 database.
127109
128110 Under the hood, Django's transaction management code:
129111
130- - opens a transaction when entering the outermost ``atomic `` block;
112+ - opens a transaction when entering the outermost ``atomic `` block
131113 - commits or rolls back the transaction when exiting the outermost block.
132114
133115.. admonition :: Performance considerations
134116
135- Open transactions have a performance cost for your database server. To
136- minimize this overhead, keep your transactions as short as possible. This
137- is especially important if you're using :func: `atomic ` in long-running
138- processes, outside of Django's request / response cycle.
117+ Open transactions have a performance cost for your database server. To minimize
118+ this overhead, keep your transactions as short as possible. This is especially
119+ important if you're using :func: `atomic ` in long-running processes, outside of
120+ Django's request / response cycle.
121+
122+ Performing actions after commit
123+ ===============================
124+
125+ The :func: `atomic ` function supports Django's :func: `~django.db.transaction.on_commit `
126+ API to :ref: `perform actions after a transaction successfully commits
127+ <performing-actions-after-commit>`.
139128
140129.. _transactions-limitations :
141130
142131Limitations
143- -----------
132+ ===========
144133
145134MongoDB's transaction limitations that are applicable to Django are:
146135
0 commit comments