|
1 ============================== |
|
2 Managing database transactions |
|
3 ============================== |
|
4 |
|
5 .. currentmodule:: django.db |
|
6 |
|
7 Django gives you a few ways to control how database transactions are managed, |
|
8 if you're using a database that supports transactions. |
|
9 |
|
10 Django's default transaction behavior |
|
11 ===================================== |
|
12 |
|
13 Django's default behavior is to run with an open transaction which it |
|
14 commits automatically when any built-in, data-altering model function is |
|
15 called. For example, if you call ``model.save()`` or ``model.delete()``, the |
|
16 change will be committed immediately. |
|
17 |
|
18 This is much like the auto-commit setting for most databases. As soon as you |
|
19 perform an action that needs to write to the database, Django produces the |
|
20 ``INSERT``/``UPDATE``/``DELETE`` statements and then does the ``COMMIT``. |
|
21 There's no implicit ``ROLLBACK``. |
|
22 |
|
23 Tying transactions to HTTP requests |
|
24 =================================== |
|
25 |
|
26 The recommended way to handle transactions in Web requests is to tie them to |
|
27 the request and response phases via Django's ``TransactionMiddleware``. |
|
28 |
|
29 It works like this: When a request starts, Django starts a transaction. If the |
|
30 response is produced without problems, Django commits any pending transactions. |
|
31 If the view function produces an exception, Django rolls back any pending |
|
32 transactions. |
|
33 |
|
34 To activate this feature, just add the ``TransactionMiddleware`` middleware to |
|
35 your :setting:`MIDDLEWARE_CLASSES` setting:: |
|
36 |
|
37 MIDDLEWARE_CLASSES = ( |
|
38 'django.middleware.cache.UpdateCacheMiddleware', |
|
39 'django.contrib.sessions.middleware.SessionMiddleware', |
|
40 'django.middleware.common.CommonMiddleware', |
|
41 'django.middleware.transaction.TransactionMiddleware', |
|
42 'django.middleware.cache.FetchFromCacheMiddleware', |
|
43 ) |
|
44 |
|
45 The order is quite important. The transaction middleware applies not only to |
|
46 view functions, but also for all middleware modules that come after it. So if |
|
47 you use the session middleware after the transaction middleware, session |
|
48 creation will be part of the transaction. |
|
49 |
|
50 The various cache middlewares are an exception: |
|
51 :class:`~django.middleware.cache.CacheMiddleware`, |
|
52 :class:`~django.middleware.cache.UpdateCacheMiddleware`, and |
|
53 :class:`~django.middleware.cache.FetchFromCacheMiddleware` are never affected. |
|
54 Even when using database caching, Django's cache backend uses its own |
|
55 database cursor (which is mapped to its own database connection internally). |
|
56 |
|
57 Controlling transaction management in views |
|
58 =========================================== |
|
59 |
|
60 For most people, implicit request-based transactions work wonderfully. However, |
|
61 if you need more fine-grained control over how transactions are managed, you |
|
62 can use Python decorators to change the way transactions are handled by a |
|
63 particular view function. All of the decorators take an option ``using`` |
|
64 parameter which should be the alias for a database connection for which the |
|
65 behavior applies to. If no alias is specified then the ``"default"`` database |
|
66 is used. |
|
67 |
|
68 .. note:: |
|
69 |
|
70 Although the examples below use view functions as examples, these |
|
71 decorators can be applied to non-view functions as well. |
|
72 |
|
73 .. _topics-db-transactions-autocommit: |
|
74 |
|
75 ``django.db.transaction.autocommit`` |
|
76 ------------------------------------ |
|
77 |
|
78 Use the ``autocommit`` decorator to switch a view function to Django's default |
|
79 commit behavior, regardless of the global transaction setting. |
|
80 |
|
81 Example:: |
|
82 |
|
83 from django.db import transaction |
|
84 |
|
85 @transaction.autocommit |
|
86 def viewfunc(request): |
|
87 .... |
|
88 |
|
89 @transaction.autocommit(using="my_other_database") |
|
90 def viewfunc2(request): |
|
91 .... |
|
92 |
|
93 Within ``viewfunc()``, transactions will be committed as soon as you call |
|
94 ``model.save()``, ``model.delete()``, or any other function that writes to the |
|
95 database. ``viewfunc2()`` will have this same behavior, but for the |
|
96 ``"my_other_database"`` connection. |
|
97 |
|
98 ``django.db.transaction.commit_on_success`` |
|
99 ------------------------------------------- |
|
100 |
|
101 Use the ``commit_on_success`` decorator to use a single transaction for |
|
102 all the work done in a function:: |
|
103 |
|
104 from django.db import transaction |
|
105 |
|
106 @transaction.commit_on_success |
|
107 def viewfunc(request): |
|
108 .... |
|
109 |
|
110 @transaction.commit_on_success(using="my_other_database") |
|
111 def viewfunc2(request): |
|
112 .... |
|
113 |
|
114 If the function returns successfully, then Django will commit all work done |
|
115 within the function at that point. If the function raises an exception, though, |
|
116 Django will roll back the transaction. |
|
117 |
|
118 ``django.db.transaction.commit_manually`` |
|
119 ----------------------------------------- |
|
120 |
|
121 Use the ``commit_manually`` decorator if you need full control over |
|
122 transactions. It tells Django you'll be managing the transaction on your own. |
|
123 |
|
124 If your view changes data and doesn't ``commit()`` or ``rollback()``, Django |
|
125 will raise a ``TransactionManagementError`` exception. |
|
126 |
|
127 Manual transaction management looks like this:: |
|
128 |
|
129 from django.db import transaction |
|
130 |
|
131 @transaction.commit_manually |
|
132 def viewfunc(request): |
|
133 ... |
|
134 # You can commit/rollback however and whenever you want |
|
135 transaction.commit() |
|
136 ... |
|
137 |
|
138 # But you've got to remember to do it yourself! |
|
139 try: |
|
140 ... |
|
141 except: |
|
142 transaction.rollback() |
|
143 else: |
|
144 transaction.commit() |
|
145 |
|
146 @transaction.commit_manually(using="my_other_database") |
|
147 def viewfunc2(request): |
|
148 .... |
|
149 |
|
150 .. admonition:: An important note to users of earlier Django releases: |
|
151 |
|
152 The database ``connection.commit()`` and ``connection.rollback()`` methods |
|
153 (called ``db.commit()`` and ``db.rollback()`` in 0.91 and earlier) no |
|
154 longer exist. They've been replaced by ``transaction.commit()`` and |
|
155 ``transaction.rollback()``. |
|
156 |
|
157 How to globally deactivate transaction management |
|
158 ================================================= |
|
159 |
|
160 Control freaks can totally disable all transaction management by setting |
|
161 ``DISABLE_TRANSACTION_MANAGEMENT`` to ``True`` in the Django settings file. |
|
162 |
|
163 If you do this, Django won't provide any automatic transaction management |
|
164 whatsoever. Middleware will no longer implicitly commit transactions, and |
|
165 you'll need to roll management yourself. This even requires you to commit |
|
166 changes done by middleware somewhere else. |
|
167 |
|
168 Thus, this is best used in situations where you want to run your own |
|
169 transaction-controlling middleware or do something really strange. In almost |
|
170 all situations, you'll be better off using the default behavior, or the |
|
171 transaction middleware, and only modify selected functions as needed. |
|
172 |
|
173 .. _topics-db-transactions-savepoints: |
|
174 |
|
175 Savepoints |
|
176 ========== |
|
177 |
|
178 A savepoint is a marker within a transaction that enables you to roll back |
|
179 part of a transaction, rather than the full transaction. Savepoints are |
|
180 available to the PostgreSQL 8 and Oracle backends. Other backends will |
|
181 provide the savepoint functions, but they are empty operations - they won't |
|
182 actually do anything. |
|
183 |
|
184 Savepoints aren't especially useful if you are using the default |
|
185 ``autocommit`` behaviour of Django. However, if you are using |
|
186 ``commit_on_success`` or ``commit_manually``, each open transaction will build |
|
187 up a series of database operations, awaiting a commit or rollback. If you |
|
188 issue a rollback, the entire transaction is rolled back. Savepoints provide |
|
189 the ability to perform a fine-grained rollback, rather than the full rollback |
|
190 that would be performed by ``transaction.rollback()``. |
|
191 |
|
192 Each of these functions takes a ``using`` argument which should be the name of |
|
193 a database for which the behavior applies. If no ``using`` argument is |
|
194 provided then the ``"default"`` database is used. |
|
195 |
|
196 Savepoints are controlled by three methods on the transaction object: |
|
197 |
|
198 .. method:: transaction.savepoint(using=None) |
|
199 |
|
200 Creates a new savepoint. This marks a point in the transaction that |
|
201 is known to be in a "good" state. |
|
202 |
|
203 Returns the savepoint ID (sid). |
|
204 |
|
205 .. method:: transaction.savepoint_commit(sid, using=None) |
|
206 |
|
207 Updates the savepoint to include any operations that have been performed |
|
208 since the savepoint was created, or since the last commit. |
|
209 |
|
210 .. method:: transaction.savepoint_rollback(sid, using=None) |
|
211 |
|
212 Rolls the transaction back to the last point at which the savepoint was |
|
213 committed. |
|
214 |
|
215 The following example demonstrates the use of savepoints:: |
|
216 |
|
217 from django.db import transaction |
|
218 |
|
219 @transaction.commit_manually |
|
220 def viewfunc(request): |
|
221 |
|
222 a.save() |
|
223 # open transaction now contains a.save() |
|
224 sid = transaction.savepoint() |
|
225 |
|
226 b.save() |
|
227 # open transaction now contains a.save() and b.save() |
|
228 |
|
229 if want_to_keep_b: |
|
230 transaction.savepoint_commit(sid) |
|
231 # open transaction still contains a.save() and b.save() |
|
232 else: |
|
233 transaction.savepoint_rollback(sid) |
|
234 # open transaction now contains only a.save() |
|
235 |
|
236 transaction.commit() |
|
237 |
|
238 Transactions in MySQL |
|
239 ===================== |
|
240 |
|
241 If you're using MySQL, your tables may or may not support transactions; it |
|
242 depends on your MySQL version and the table types you're using. (By |
|
243 "table types," we mean something like "InnoDB" or "MyISAM".) MySQL transaction |
|
244 peculiarities are outside the scope of this article, but the MySQL site has |
|
245 `information on MySQL transactions`_. |
|
246 |
|
247 If your MySQL setup does *not* support transactions, then Django will function |
|
248 in auto-commit mode: Statements will be executed and committed as soon as |
|
249 they're called. If your MySQL setup *does* support transactions, Django will |
|
250 handle transactions as explained in this document. |
|
251 |
|
252 .. _information on MySQL transactions: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html |
|
253 |
|
254 Handling exceptions within PostgreSQL transactions |
|
255 ================================================== |
|
256 |
|
257 When a call to a PostgreSQL cursor raises an exception (typically |
|
258 ``IntegrityError``), all subsequent SQL in the same transaction will fail with |
|
259 the error "current transaction is aborted, queries ignored until end of |
|
260 transaction block". Whilst simple use of ``save()`` is unlikely to raise an |
|
261 exception in PostgreSQL, there are more advanced usage patterns which |
|
262 might, such as saving objects with unique fields, saving using the |
|
263 force_insert/force_update flag, or invoking custom SQL. |
|
264 |
|
265 There are several ways to recover from this sort of error. |
|
266 |
|
267 Transaction rollback |
|
268 -------------------- |
|
269 |
|
270 The first option is to roll back the entire transaction. For example:: |
|
271 |
|
272 a.save() # Succeeds, but may be undone by transaction rollback |
|
273 try: |
|
274 b.save() # Could throw exception |
|
275 except IntegrityError: |
|
276 transaction.rollback() |
|
277 c.save() # Succeeds, but a.save() may have been undone |
|
278 |
|
279 Calling ``transaction.rollback()`` rolls back the entire transaction. Any |
|
280 uncommitted database operations will be lost. In this example, the changes |
|
281 made by ``a.save()`` would be lost, even though that operation raised no error |
|
282 itself. |
|
283 |
|
284 Savepoint rollback |
|
285 ------------------ |
|
286 |
|
287 If you are using PostgreSQL 8 or later, you can use :ref:`savepoints |
|
288 <topics-db-transactions-savepoints>` to control the extent of a rollback. |
|
289 Before performing a database operation that could fail, you can set or update |
|
290 the savepoint; that way, if the operation fails, you can roll back the single |
|
291 offending operation, rather than the entire transaction. For example:: |
|
292 |
|
293 a.save() # Succeeds, and never undone by savepoint rollback |
|
294 try: |
|
295 sid = transaction.savepoint() |
|
296 b.save() # Could throw exception |
|
297 transaction.savepoint_commit(sid) |
|
298 except IntegrityError: |
|
299 transaction.savepoint_rollback(sid) |
|
300 c.save() # Succeeds, and a.save() is never undone |
|
301 |
|
302 In this example, ``a.save()`` will not be undone in the case where |
|
303 ``b.save()`` raises an exception. |
|
304 |
|
305 Database-level autocommit |
|
306 ------------------------- |
|
307 |
|
308 .. versionadded:: 1.1 |
|
309 |
|
310 With PostgreSQL 8.2 or later, there is an advanced option to run PostgreSQL |
|
311 with :doc:`database-level autocommit </ref/databases>`. If you use this option, |
|
312 there is no constantly open transaction, so it is always possible to continue |
|
313 after catching an exception. For example:: |
|
314 |
|
315 a.save() # succeeds |
|
316 try: |
|
317 b.save() # Could throw exception |
|
318 except IntegrityError: |
|
319 pass |
|
320 c.save() # succeeds |
|
321 |
|
322 .. note:: |
|
323 |
|
324 This is not the same as the :ref:`autocommit decorator |
|
325 <topics-db-transactions-autocommit>`. When using database level autocommit |
|
326 there is no database transaction at all. The ``autocommit`` decorator |
|
327 still uses transactions, automatically committing each transaction when |
|
328 a database modifying operation occurs. |