Proof-read and adjusted the transactions docs.

This commit is contained in:
Aymeric Augustin 2013-03-13 14:47:48 +01:00
parent 93af822c00
commit 5d8342f321
3 changed files with 42 additions and 45 deletions

View File

@ -329,14 +329,19 @@ these changes.
1.8 1.8
--- ---
* ``django.contrib.comments`` will be removed.
* The following transaction management APIs will be removed: * The following transaction management APIs will be removed:
- ``TransactionMiddleware``, - ``TransactionMiddleware``,
- the decorators and context managers ``autocommit``, ``commit_on_success``, - the decorators and context managers ``autocommit``, ``commit_on_success``,
and ``commit_manually``, and ``commit_manually``, defined in ``django.db.transaction``,
- the functions ``commit_unless_managed`` and ``rollback_unless_managed``,
also defined in ``django.db.transaction``,
- the ``TRANSACTIONS_MANAGED`` setting. - the ``TRANSACTIONS_MANAGED`` setting.
Upgrade paths are described in :ref:`transactions-upgrading-from-1.5`. Upgrade paths are described in the :ref:`transaction management docs
<transactions-upgrading-from-1.5>`.
* The :ttag:`cycle` and :ttag:`firstof` template tags will auto-escape their * The :ttag:`cycle` and :ttag:`firstof` template tags will auto-escape their
arguments. In 1.6 and 1.7, this behavior is provided by the version of these arguments. In 1.6 and 1.7, this behavior is provided by the version of these
@ -358,14 +363,11 @@ these changes.
``ChangeList.root_query_set`` and ``ChangeList.query_set``. ``ChangeList.root_query_set`` and ``ChangeList.query_set``.
* The following private APIs will be removed: * The following private APIs will be removed:
- ``django.db.close_connection()`` - ``django.db.close_connection()``
- ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()`` - ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()``
- ``django.db.transaction.is_managed()`` - ``django.db.transaction.is_managed()``
- ``django.db.transaction.managed()`` - ``django.db.transaction.managed()``
- ``django.db.transaction.commit_unless_managed()``
- ``django.db.transaction.rollback_unless_managed()``
* ``django.contrib.comments`` will be removed.
2.0 2.0
--- ---

View File

@ -36,7 +36,8 @@ Improved transaction management
Django's transaction management was overhauled. Database-level autocommit is Django's transaction management was overhauled. Database-level autocommit is
now turned on by default. This makes transaction handling more explicit and now turned on by default. This makes transaction handling more explicit and
should improve performance. The existing APIs were deprecated, and new APIs should improve performance. The existing APIs were deprecated, and new APIs
were introduced, as described in :doc:`/topics/db/transactions`. were introduced, as described in the :doc:`transaction management docs
</topics/db/transactions>`.
Please review carefully the list of :ref:`known backwards-incompatibilities Please review carefully the list of :ref:`known backwards-incompatibilities
<transactions-upgrading-from-1.5>` to determine if you need to make changes in <transactions-upgrading-from-1.5>` to determine if you need to make changes in

View File

@ -35,10 +35,10 @@ transaction. Set :setting:`ATOMIC_REQUESTS <DATABASE-ATOMIC_REQUESTS>` to
``True`` in the configuration of each database for which you want to enable ``True`` in the configuration of each database for which you want to enable
this behavior. this behavior.
It works like this. When a request starts, Django starts a transaction. If the It works like this. Before calling a view function, Django starts a
response is produced without problems, Django commits the transaction. If the transaction. If the response is produced without problems, Django commits the
view function produces an exception, Django rolls back the transaction. transaction. If the view produces an exception, Django rolls back the
Middleware always runs outside of this transaction. transaction.
You may perfom partial commits and rollbacks in your view code, typically with You may perfom partial commits and rollbacks in your view code, typically with
the :func:`atomic` context manager. However, at the end of the view, either the :func:`atomic` context manager. However, at the end of the view, either
@ -207,13 +207,6 @@ To avoid this, you can :ref:`deactivate the transaction management
Before Django 1.6, autocommit was turned off, and it was emulated by Before Django 1.6, autocommit was turned off, and it was emulated by
forcing a commit after write operations in the ORM. forcing a commit after write operations in the ORM.
.. warning::
If you're using the database API directly — for instance, you're running
SQL queries with ``cursor.execute()`` — be aware that autocommit is on,
and consider wrapping your operations in a transaction, with
:func:`atomic`, to ensure consistency.
.. _deactivate-transaction-management: .. _deactivate-transaction-management:
Deactivating transaction management Deactivating transaction management
@ -251,8 +244,8 @@ Autocommit
.. versionadded:: 1.6 .. versionadded:: 1.6
Django provides a straightforward API to manage the autocommit state of each Django provides a straightforward API in the :mod:`django.db.transaction`
database connection, if you need to. module to manage the autocommit state of each database connection.
.. function:: get_autocommit(using=None) .. function:: get_autocommit(using=None)
@ -287,7 +280,7 @@ start a transaction is to disable autocommit with :func:`set_autocommit`.
Once you're in a transaction, you can choose either to apply the changes Once you're in a transaction, you can choose either to apply the changes
you've performed until this point with :func:`commit`, or to cancel them with you've performed until this point with :func:`commit`, or to cancel them with
:func:`rollback`. :func:`rollback`. These functions are defined in :mod:`django.db.transaction`.
.. function:: commit(using=None) .. function:: commit(using=None)
@ -332,10 +325,8 @@ Savepoints are controlled by three functions in :mod:`django.db.transaction`:
.. function:: savepoint(using=None) .. function:: savepoint(using=None)
Creates a new savepoint. This marks a point in the transaction that Creates a new savepoint. This marks a point in the transaction that is
is known to be in a "good" state. known to be in a "good" state. Returns the savepoint ID (``sid``).
Returns the savepoint ID (``sid``).
.. function:: savepoint_commit(sid, using=None) .. function:: savepoint_commit(sid, using=None)
@ -388,11 +379,9 @@ While SQLite ≥ 3.6.8 supports savepoints, a flaw in the design of the
:mod:`sqlite3` makes them hardly usable. :mod:`sqlite3` makes them hardly usable.
When autocommit is enabled, savepoints don't make sense. When it's disabled, When autocommit is enabled, savepoints don't make sense. When it's disabled,
:mod:`sqlite3` commits implicitly before savepoint-related statement. (It :mod:`sqlite3` commits implicitly before savepoint statements. (In fact, it
commits before any statement other than ``SELECT``, ``INSERT``, ``UPDATE``, commits before any statement other than ``SELECT``, ``INSERT``, ``UPDATE``,
``DELETE`` and ``REPLACE``.) ``DELETE`` and ``REPLACE``.) This bug has two consequences:
This has two consequences:
- The low level APIs for savepoints are only usable inside a transaction ie. - The low level APIs for savepoints are only usable inside a transaction ie.
inside an :func:`atomic` block. inside an :func:`atomic` block.
@ -407,22 +396,27 @@ depends on your MySQL version and the table types you're using. (By
peculiarities are outside the scope of this article, but the MySQL site has peculiarities are outside the scope of this article, but the MySQL site has
`information on MySQL transactions`_. `information on MySQL transactions`_.
If your MySQL setup does *not* support transactions, then Django will function If your MySQL setup does *not* support transactions, then Django will always
in autocommit mode: Statements will be executed and committed as soon as function in autocommit mode: statements will be executed and committed as soon
they're called. If your MySQL setup *does* support transactions, Django will as they're called. If your MySQL setup *does* support transactions, Django
handle transactions as explained in this document. 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 .. _information on MySQL transactions: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html
Handling exceptions within PostgreSQL transactions Handling exceptions within PostgreSQL transactions
-------------------------------------------------- --------------------------------------------------
When a call to a PostgreSQL cursor raises an exception (typically .. note::
``IntegrityError``), all subsequent SQL in the same transaction will fail with This section is relevant only if you're implementing your own transaction
the error "current transaction is aborted, queries ignored until end of management. This problem cannot occur in Django's default mode and
transaction block". Whilst simple use of ``save()`` is unlikely to raise an :func:`atomic` handles it automatically.
exception in PostgreSQL, there are more advanced usage patterns which
might, such as saving objects with unique fields, saving using the Inside a transaction, 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. force_insert/force_update flag, or invoking custom SQL.
There are several ways to recover from this sort of error. There are several ways to recover from this sort of error.
@ -529,9 +523,9 @@ Django starts in auto mode. ``TransactionMiddleware``,
Internally, Django keeps a stack of states. Activations and deactivations must Internally, Django keeps a stack of states. Activations and deactivations must
be balanced. be balanced.
For example, ``commit_on_success`` switches to managed mode when entering the For example, :func:`commit_on_success` switches to managed mode when entering
block of code it controls; when exiting the block, it commits or rollbacks, the block of code it controls; when exiting the block, it commits or
and switches back to auto mode. rollbacks, and switches back to auto mode.
So :func:`commit_on_success` really has two effects: it changes the So :func:`commit_on_success` really has two effects: it changes the
transaction state and it defines an transaction block. Nesting will give the transaction state and it defines an transaction block. Nesting will give the
@ -568,7 +562,7 @@ you must now use this pattern::
my_view.transactions_per_request = False my_view.transactions_per_request = False
The transaction middleware applied not only to view functions, but also to The transaction middleware applied not only to view functions, but also to
middleware modules that come after it. For instance, if you used the session middleware modules that came after it. For instance, if you used the session
middleware after the transaction middleware, session creation was part of the middleware after the transaction middleware, session creation was part of the
transaction. :setting:`ATOMIC_REQUESTS <DATABASE-ATOMIC_REQUESTS>` only transaction. :setting:`ATOMIC_REQUESTS <DATABASE-ATOMIC_REQUESTS>` only
applies to the view itself. applies to the view itself.
@ -651,8 +645,8 @@ same "automatic transaction". If you need to enforce atomicity, you must wrap
the sequence of queries in :func:`commit_on_success`. the sequence of queries in :func:`commit_on_success`.
To check for this problem, look for calls to ``cursor.execute()``. They're To check for this problem, look for calls to ``cursor.execute()``. They're
usually followed by a call to ``transaction.commit_unless_managed``, which usually followed by a call to ``transaction.commit_unless_managed()``, which
isn't necessary any more and should be removed. isn't useful any more and should be removed.
Select for update Select for update
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~