@@ -4,100 +4,87 @@ Transactions
4
4
5
5
.. versionadded :: 5.2.0b2
6
6
7
- .. module :: django_mongod_backend .transaction
7
+ .. module :: django_mongodb_backend .transaction
8
8
9
9
MongoDB supports :doc: `transactions <manual:core/transactions >` if it's configured as a
10
10
:doc: `replica set <manual:replication >` or a :doc: `sharded cluster <manual:sharding >`.
11
11
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.
14
16
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 .
17
19
18
20
Outside of a transaction, query execution uses Django and MongoDB's default behavior of
19
21
autocommit mode. Each query is immediately committed to the database.
20
22
21
23
Controlling transactions
22
- ------------------------
24
+ ========================
23
25
24
26
.. function :: atomic(using=None, durable=False)
25
27
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.
31
32
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.
41
37
42
38
``atomic `` is usable both as a :py:term: `decorator `::
43
39
44
- from django.db import transaction
40
+ from django_mongodb_backend import transaction
45
41
46
42
47
- @transaction. atomic
43
+ @atomic
48
44
def viewfunc(request):
49
45
# This code executes inside a transaction.
50
46
do_stuff()
51
47
52
48
and as a :py:term: `context manager `::
53
49
54
- from django.db import transaction
50
+ from django_mongodb_backend import transaction
55
51
56
52
57
53
def viewfunc(request):
58
54
# This code executes in autocommit mode (Django's default).
59
55
do_stuff()
60
56
61
- with transaction. atomic():
57
+ with atomic():
62
58
# This code executes inside a transaction.
63
59
do_more_stuff()
64
60
65
61
.. admonition :: Avoid catching exceptions inside ``atomic``!
66
62
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
80
74
an exception.
81
75
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
-
90
76
.. admonition :: You may need to manually revert app state when rolling back a transaction.
91
77
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.
95
81
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::
99
85
100
- from django.db import DatabaseError, transaction
86
+ from django_mongodb_backend import transaction
87
+ from django.db import DatabaseError
101
88
102
89
obj = MyModel(active=False)
103
90
obj.active = True
@@ -110,37 +97,39 @@ Controlling transactions
110
97
if obj.active:
111
98
...
112
99
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.
123
105
124
106
``atomic `` takes a ``using `` argument which should be the name of a
125
107
database. If this argument isn't provided, Django uses the ``"default" ``
126
108
database.
127
109
128
110
Under the hood, Django's transaction management code:
129
111
130
- - opens a transaction when entering the outermost ``atomic `` block;
112
+ - opens a transaction when entering the outermost ``atomic `` block
131
113
- commits or rolls back the transaction when exiting the outermost block.
132
114
133
115
.. admonition :: Performance considerations
134
116
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>`.
139
128
140
129
.. _transactions-limitations :
141
130
142
131
Limitations
143
- -----------
132
+ ===========
144
133
145
134
MongoDB's transaction limitations that are applicable to Django are:
146
135
0 commit comments