mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	git-svn-id: http://code.djangoproject.com/svn/django/trunk@3436 bcc190cf-cafb-0310-a4f2-bffc1f526a37
		
			
				
	
	
		
			164 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ==============================
 | |
| Managing database transactions
 | |
| ==============================
 | |
| 
 | |
| Django gives you a few ways to control how database transactions are managed,
 | |
| if you're using a database that supports transactions.
 | |
| 
 | |
| Django's default transaction behavior
 | |
| =====================================
 | |
| 
 | |
| Django's default behavior is to commit automatically when any built-in,
 | |
| data-altering model function is called. For example, if you call
 | |
| ``model.save()`` or ``model.delete()``, the change will be committed
 | |
| immediately.
 | |
| 
 | |
| This is much like the auto-commit setting for most databases. As soon as you
 | |
| perform an action that needs to write to the database, Django produces the
 | |
| ``INSERT``/``UPDATE``/``DELETE`` statements and then does the ``COMMIT``.
 | |
| There's no implicit ``ROLLBACK``.
 | |
| 
 | |
| Tying transactions to HTTP requests
 | |
| ===================================
 | |
| 
 | |
| The recommended way to handle transactions in Web requests is to tie them to
 | |
| the request and response phases via Django's ``TransactionMiddleware``.
 | |
| 
 | |
| It works like this: When a request starts, Django starts a transaction. If the
 | |
| response is produced without problems, Django commits any pending transactions.
 | |
| If the view function produces an exception, Django rolls back any pending
 | |
| transactions.
 | |
| 
 | |
| To activate this feature, just add the ``TransactionMiddleware`` middleware to
 | |
| your ``MIDDLEWARE_CLASSES`` setting::
 | |
| 
 | |
|     MIDDLEWARE_CLASSES = (
 | |
|         'django.contrib.sessions.middleware.SessionMiddleware',
 | |
|         'django.middleware.common.CommonMiddleware',
 | |
|         'django.middleware.cache.CacheMiddleware',
 | |
|         'django.middleware.transaction.TransactionMiddleware',
 | |
|     )
 | |
| 
 | |
| The order is quite important. The transaction middleware applies not only to
 | |
| view functions, but also for all middleware modules that come after it. So if
 | |
| you use the session middleware after the transaction middleware, session
 | |
| creation will be part of the transaction.
 | |
| 
 | |
| An exception is ``CacheMiddleware``, which is never affected. The cache
 | |
| middleware uses its own database cursor (which is mapped to its own database
 | |
| connection internally).
 | |
| 
 | |
| Controlling transaction management in views
 | |
| ===========================================
 | |
| 
 | |
| For most people, implicit request-based transactions work wonderfully. However,
 | |
| if you need more fine-grained control over how transactions are managed, you
 | |
| can use Python decorators to change the way transactions are handled by a
 | |
| particular view function.
 | |
| 
 | |
| .. note::
 | |
| 
 | |
|     Although the examples below use view functions as examples, these
 | |
|     decorators can be applied to non-view functions as well.
 | |
| 
 | |
| ``django.db.transaction.autocommit``
 | |
| ------------------------------------
 | |
| 
 | |
| Use the ``autocommit`` decorator to switch a view function to Django's default
 | |
| commit behavior, regardless of the global transaction setting.
 | |
| 
 | |
| Example::
 | |
| 
 | |
|     from django.db import transaction
 | |
| 
 | |
|     @transaction.autocommit
 | |
|     def viewfunc(request):
 | |
|         ....
 | |
| 
 | |
| Within ``viewfunc()``, transactions will be committed as soon as you call
 | |
| ``model.save()``, ``model.delete()``, or any other function that writes to the
 | |
| database.
 | |
| 
 | |
| ``django.db.transaction.commit_on_success``
 | |
| -------------------------------------------
 | |
| 
 | |
| Use the ``commit_on_success`` decorator to use a single transaction for
 | |
| all the work done in a function::
 | |
| 
 | |
|     from django.db import transaction
 | |
| 
 | |
|     @transaction.commit_on_success
 | |
|     def viewfunc(request):
 | |
|         ....
 | |
| 
 | |
| If the function returns successfully, then Django will commit all work done
 | |
| within the function at that point. If the function raises an exception, though,
 | |
| Django will roll back the transaction.
 | |
| 
 | |
| ``django.db.transaction.commit_manually``
 | |
| -----------------------------------------
 | |
| 
 | |
| Use the ``commit_manually`` decorator if you need full control over
 | |
| transactions. It tells Django you'll be managing the transaction on your own.
 | |
| 
 | |
| If your view changes data and doesn't ``commit()`` or ``rollback()``, Django
 | |
| will raise a ``TransactionManagementError`` exception.
 | |
| 
 | |
| Manual transaction management looks like this::
 | |
| 
 | |
|     from django.db import transaction
 | |
| 
 | |
|     @transaction.commit_manually
 | |
|     def viewfunc(request):
 | |
|         ...
 | |
|         # You can commit/rollback however and whenever you want
 | |
|         transaction.commit()
 | |
|         ...
 | |
| 
 | |
|         # But you've got to remember to do it yourself!
 | |
|         try:
 | |
|             ...
 | |
|         except:
 | |
|             transaction.rollback()
 | |
|         else:
 | |
|             transaction.commit()
 | |
| 
 | |
| .. admonition:: An important note to users of earlier Django releases:
 | |
| 
 | |
|     The database ``connection.commit()`` and ``connection.rollback()`` methods
 | |
|     (called ``db.commit()`` and ``db.rollback()`` in 0.91 and earlier) no longer
 | |
|     exist. They've been replaced by ``transaction.commit()`` and
 | |
|     ``transaction.rollback()``.
 | |
| 
 | |
| How to globally deactivate transaction management
 | |
| =================================================
 | |
| 
 | |
| Control freaks can totally disable all transaction management by setting
 | |
| ``DISABLE_TRANSACTION_MANAGEMENT`` to ``True`` in the Django settings file.
 | |
| 
 | |
| If you do this, Django won't provide any automatic transaction management
 | |
| whatsoever. Middleware will no longer implicitly commit transactions, and
 | |
| you'll need to roll management yourself. This even requires you to commit
 | |
| changes done by middleware somewhere else.
 | |
| 
 | |
| Thus, this is best used in situations where you want to run your own
 | |
| transaction-controlling middleware or do something really strange. In almost
 | |
| all situations, you'll be better off using the default behavior, or the
 | |
| transaction middleware, and only modify selected functions as needed.
 | |
| 
 | |
| Transactions in MySQL
 | |
| =====================
 | |
| 
 | |
| If you're using MySQL, your tables may or may not support transactions; it
 | |
| depends on your MySQL version and the table types you're using. (By
 | |
| "table types," we mean something like "InnoDB" or "MyISAM".) MySQL transaction
 | |
| peculiarities are outside the scope of this article, but the MySQL site has
 | |
| `information on MySQL transactions`_.
 | |
| 
 | |
| If your MySQL setup does *not* support transactions, then Django will function
 | |
| in auto-commit mode: Statements will be executed and committed as soon as
 | |
| they're called. If your MySQL setup *does* support transactions, Django will
 | |
| handle transactions as explained in this document.
 | |
| 
 | |
| .. _information on MySQL transactions: http://dev.mysql.com/books/mysqlpress/mysql-tutorial/ch10.html
 |