|
1 ============================== |
|
2 Managing database transactions |
|
3 ============================== |
|
4 |
|
5 Django gives you a few ways to control how database transactions are managed, |
|
6 if you're using a database that supports transactions. |
|
7 |
|
8 Django's default transaction behavior |
|
9 ===================================== |
|
10 |
|
11 Django's default behavior is to commit automatically when any built-in, |
|
12 data-altering model function is called. For example, if you call |
|
13 ``model.save()`` or ``model.delete()``, the change will be committed |
|
14 immediately. |
|
15 |
|
16 This is much like the auto-commit setting for most databases. As soon as you |
|
17 perform an action that needs to write to the database, Django produces the |
|
18 ``INSERT``/``UPDATE``/``DELETE`` statements and then does the ``COMMIT``. |
|
19 There's no implicit ``ROLLBACK``. |
|
20 |
|
21 Tying transactions to HTTP requests |
|
22 =================================== |
|
23 |
|
24 The recommended way to handle transactions in Web requests is to tie them to |
|
25 the request and response phases via Django's ``TransactionMiddleware``. |
|
26 |
|
27 It works like this: When a request starts, Django starts a transaction. If the |
|
28 response is produced without problems, Django commits any pending transactions. |
|
29 If the view function produces an exception, Django rolls back any pending |
|
30 transactions. |
|
31 |
|
32 To activate this feature, just add the ``TransactionMiddleware`` middleware to |
|
33 your ``MIDDLEWARE_CLASSES`` setting:: |
|
34 |
|
35 MIDDLEWARE_CLASSES = ( |
|
36 'django.contrib.sessions.middleware.SessionMiddleware', |
|
37 'django.middleware.common.CommonMiddleware', |
|
38 'django.middleware.cache.CacheMiddleware', |
|
39 'django.middleware.transaction.TransactionMiddleware', |
|
40 ) |
|
41 |
|
42 The order is quite important. The transaction middleware applies not only to |
|
43 view functions, but also for all middleware modules that come after it. So if |
|
44 you use the session middleware after the transaction middleware, session |
|
45 creation will be part of the transaction. |
|
46 |
|
47 An exception is ``CacheMiddleware``, which is never affected. The cache |
|
48 middleware uses its own database cursor (which is mapped to its own database |
|
49 connection internally). |
|
50 |
|
51 Controlling transaction management in views |
|
52 =========================================== |
|
53 |
|
54 For most people, implicit request-based transactions work wonderfully. However, |
|
55 if you need more fine-grained control over how transactions are managed, you |
|
56 can use Python decorators to change the way transactions are handled by a |
|
57 particular view function. |
|
58 |
|
59 .. note:: |
|
60 |
|
61 Although the examples below use view functions as examples, these |
|
62 decorators can be applied to non-view functions as well. |
|
63 |
|
64 ``django.db.transaction.autocommit`` |
|
65 ------------------------------------ |
|
66 |
|
67 Use the ``autocommit`` decorator to switch a view function to Django's default |
|
68 commit behavior, regardless of the global transaction setting. |
|
69 |
|
70 Example:: |
|
71 |
|
72 from django.db import transaction |
|
73 |
|
74 @transaction.autocommit |
|
75 def viewfunc(request): |
|
76 .... |
|
77 |
|
78 Within ``viewfunc()``, transactions will be committed as soon as you call |
|
79 ``model.save()``, ``model.delete()``, or any other function that writes to the |
|
80 database. |
|
81 |
|
82 ``django.db.transaction.commit_on_success`` |
|
83 ------------------------------------------- |
|
84 |
|
85 Use the ``commit_on_success`` decorator to use a single transaction for |
|
86 all the work done in a function:: |
|
87 |
|
88 from django.db import transaction |
|
89 |
|
90 @transaction.commit_on_success |
|
91 def viewfunc(request): |
|
92 .... |
|
93 |
|
94 If the function returns successfully, then Django will commit all work done |
|
95 within the function at that point. If the function raises an exception, though, |
|
96 Django will roll back the transaction. |
|
97 |
|
98 ``django.db.transaction.commit_manually`` |
|
99 ----------------------------------------- |
|
100 |
|
101 Use the ``commit_manually`` decorator if you need full control over |
|
102 transactions. It tells Django you'll be managing the transaction on your own. |
|
103 |
|
104 If your view changes data and doesn't ``commit()`` or ``rollback()``, Django |
|
105 will raise a ``TransactionManagementError`` exception. |
|
106 |
|
107 Manual transaction management looks like this:: |
|
108 |
|
109 from django.db import transaction |
|
110 |
|
111 @transaction.commit_manually |
|
112 def viewfunc(request): |
|
113 ... |
|
114 # You can commit/rollback however and whenever you want |
|
115 transaction.commit() |
|
116 ... |
|
117 |
|
118 # But you've got to remember to do it yourself! |
|
119 try: |
|
120 ... |
|
121 except: |
|
122 transaction.rollback() |
|
123 else: |
|
124 transaction.commit() |
|
125 |
|
126 .. admonition:: An important note to users of earlier Django releases: |
|
127 |
|
128 The database ``connection.commit()`` and ``connection.rollback()`` methods |
|
129 (called ``db.commit()`` and ``db.rollback()`` in 0.91 and earlier) no longer |
|
130 exist. They've been replaced by ``transaction.commit()`` and |
|
131 ``transaction.rollback()``. |
|
132 |
|
133 How to globally deactivate transaction management |
|
134 ================================================= |
|
135 |
|
136 Control freaks can totally disable all transaction management by setting |
|
137 ``DISABLE_TRANSACTION_MANAGEMENT`` to ``True`` in the Django settings file. |
|
138 |
|
139 If you do this, Django won't provide any automatic transaction management |
|
140 whatsoever. Middleware will no longer implicitly commit transactions, and |
|
141 you'll need to roll management yourself. This even requires you to commit |
|
142 changes done by middleware somewhere else. |
|
143 |
|
144 Thus, this is best used in situations where you want to run your own |
|
145 transaction-controlling middleware or do something really strange. In almost |
|
146 all situations, you'll be better off using the default behavior, or the |
|
147 transaction middleware, and only modify selected functions as needed. |
|
148 |
|
149 Transactions in MySQL |
|
150 ===================== |
|
151 |
|
152 If you're using MySQL, your tables may or may not support transactions; it |
|
153 depends on your MySQL version and the table types you're using. (By |
|
154 "table types," we mean something like "InnoDB" or "MyISAM".) MySQL transaction |
|
155 peculiarities are outside the scope of this article, but the MySQL site has |
|
156 `information on MySQL transactions`_. |
|
157 |
|
158 If your MySQL setup does *not* support transactions, then Django will function |
|
159 in auto-commit mode: Statements will be executed and committed as soon as |
|
160 they're called. If your MySQL setup *does* support transactions, Django will |
|
161 handle transactions as explained in this document. |
|
162 |
|
163 .. _information on MySQL transactions: http://dev.mysql.com/books/mysqlpress/mysql-tutorial/ch10.html |