diff options
Diffstat (limited to 'parts/django/docs/topics/db/transactions.txt')
-rw-r--r-- | parts/django/docs/topics/db/transactions.txt | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/parts/django/docs/topics/db/transactions.txt b/parts/django/docs/topics/db/transactions.txt deleted file mode 100644 index be9d9a8..0000000 --- a/parts/django/docs/topics/db/transactions.txt +++ /dev/null @@ -1,328 +0,0 @@ -============================== -Managing database transactions -============================== - -.. currentmodule:: django.db - -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 run with an open transaction which it -commits 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 :setting:`MIDDLEWARE_CLASSES` setting:: - - MIDDLEWARE_CLASSES = ( - 'django.middleware.cache.UpdateCacheMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.transaction.TransactionMiddleware', - 'django.middleware.cache.FetchFromCacheMiddleware', - ) - -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. - -The various cache middlewares are an exception: -:class:`~django.middleware.cache.CacheMiddleware`, -:class:`~django.middleware.cache.UpdateCacheMiddleware`, and -:class:`~django.middleware.cache.FetchFromCacheMiddleware` are never affected. -Even when using database caching, Django's cache backend 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. All of the decorators take an option ``using`` -parameter which should be the alias for a database connection for which the -behavior applies to. If no alias is specified then the ``"default"`` database -is used. - -.. note:: - - Although the examples below use view functions as examples, these - decorators can be applied to non-view functions as well. - -.. _topics-db-transactions-autocommit: - -``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): - .... - - @transaction.autocommit(using="my_other_database") - def viewfunc2(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. ``viewfunc2()`` will have this same behavior, but for the -``"my_other_database"`` connection. - -``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): - .... - - @transaction.commit_on_success(using="my_other_database") - def viewfunc2(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() - - @transaction.commit_manually(using="my_other_database") - def viewfunc2(request): - .... - -.. 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. - -.. _topics-db-transactions-savepoints: - -Savepoints -========== - -A savepoint is a marker within a transaction that enables you to roll back -part of a transaction, rather than the full transaction. Savepoints are -available to the PostgreSQL 8 and Oracle backends. Other backends will -provide the savepoint functions, but they are empty operations - they won't -actually do anything. - -Savepoints aren't especially useful if you are using the default -``autocommit`` behaviour of Django. However, if you are using -``commit_on_success`` or ``commit_manually``, each open transaction will build -up a series of database operations, awaiting a commit or rollback. If you -issue a rollback, the entire transaction is rolled back. Savepoints provide -the ability to perform a fine-grained rollback, rather than the full rollback -that would be performed by ``transaction.rollback()``. - -Each of these functions takes a ``using`` argument which should be the name of -a database for which the behavior applies. If no ``using`` argument is -provided then the ``"default"`` database is used. - -Savepoints are controlled by three methods on the transaction object: - -.. method:: transaction.savepoint(using=None) - - Creates a new savepoint. This marks a point in the transaction that - is known to be in a "good" state. - - Returns the savepoint ID (sid). - -.. method:: transaction.savepoint_commit(sid, using=None) - - Updates the savepoint to include any operations that have been performed - since the savepoint was created, or since the last commit. - -.. method:: transaction.savepoint_rollback(sid, using=None) - - Rolls the transaction back to the last point at which the savepoint was - committed. - -The following example demonstrates the use of savepoints:: - - from django.db import transaction - - @transaction.commit_manually - def viewfunc(request): - - a.save() - # open transaction now contains a.save() - sid = transaction.savepoint() - - b.save() - # open transaction now contains a.save() and b.save() - - if want_to_keep_b: - transaction.savepoint_commit(sid) - # open transaction still contains a.save() and b.save() - else: - transaction.savepoint_rollback(sid) - # open transaction now contains only a.save() - - transaction.commit() - -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/doc/refman/5.0/en/sql-syntax-transactions.html - -Handling exceptions within PostgreSQL transactions -================================================== - -When a call to a PostgreSQL cursor raises an exception (typically -``IntegrityError``), all subsequent SQL in the same transaction will fail with -the error "current transaction is aborted, queries ignored until end of -transaction block". Whilst simple use of ``save()`` is unlikely to raise an -exception in PostgreSQL, there are more advanced usage patterns which -might, such as saving objects with unique fields, saving using the -force_insert/force_update flag, or invoking custom SQL. - -There are several ways to recover from this sort of error. - -Transaction rollback --------------------- - -The first option is to roll back the entire transaction. For example:: - - a.save() # Succeeds, but may be undone by transaction rollback - try: - b.save() # Could throw exception - except IntegrityError: - transaction.rollback() - c.save() # Succeeds, but a.save() may have been undone - -Calling ``transaction.rollback()`` rolls back the entire transaction. Any -uncommitted database operations will be lost. In this example, the changes -made by ``a.save()`` would be lost, even though that operation raised no error -itself. - -Savepoint rollback ------------------- - -If you are using PostgreSQL 8 or later, you can use :ref:`savepoints -<topics-db-transactions-savepoints>` to control the extent of a rollback. -Before performing a database operation that could fail, you can set or update -the savepoint; that way, if the operation fails, you can roll back the single -offending operation, rather than the entire transaction. For example:: - - a.save() # Succeeds, and never undone by savepoint rollback - try: - sid = transaction.savepoint() - b.save() # Could throw exception - transaction.savepoint_commit(sid) - except IntegrityError: - transaction.savepoint_rollback(sid) - c.save() # Succeeds, and a.save() is never undone - -In this example, ``a.save()`` will not be undone in the case where -``b.save()`` raises an exception. - -Database-level autocommit -------------------------- - -.. versionadded:: 1.1 - -With PostgreSQL 8.2 or later, there is an advanced option to run PostgreSQL -with :doc:`database-level autocommit </ref/databases>`. If you use this option, -there is no constantly open transaction, so it is always possible to continue -after catching an exception. For example:: - - a.save() # succeeds - try: - b.save() # Could throw exception - except IntegrityError: - pass - c.save() # succeeds - -.. note:: - - This is not the same as the :ref:`autocommit decorator - <topics-db-transactions-autocommit>`. When using database level autocommit - there is no database transaction at all. The ``autocommit`` decorator - still uses transactions, automatically committing each transaction when - a database modifying operation occurs. |