Removed docs for removed transaction APIs.
This commit is contained in:
parent
99d40c6f65
commit
6b8c969878
|
@ -356,9 +356,6 @@ details on these changes.
|
||||||
also defined in ``django.db.transaction``,
|
also defined in ``django.db.transaction``,
|
||||||
- the ``TRANSACTIONS_MANAGED`` setting.
|
- the ``TRANSACTIONS_MANAGED`` setting.
|
||||||
|
|
||||||
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
|
||||||
tags in the ``future`` template tag library.
|
tags in the ``future`` template tag library.
|
||||||
|
|
|
@ -625,8 +625,7 @@ performed.
|
||||||
As a result of this change, you no longer need to set a transaction
|
As a result of this change, you no longer need to set a transaction
|
||||||
dirty explicitly when you execute raw SQL or use a data-modifying
|
dirty explicitly when you execute raw SQL or use a data-modifying
|
||||||
``SELECT``. However, you *do* need to explicitly close any read-only
|
``SELECT``. However, you *do* need to explicitly close any read-only
|
||||||
transactions that are being managed using
|
transactions that are being managed using ``commit_manually()``. For example::
|
||||||
:func:`~django.db.transaction.commit_manually`. For example::
|
|
||||||
|
|
||||||
@transaction.commit_manually
|
@transaction.commit_manually
|
||||||
def my_view(request, name):
|
def my_view(request, name):
|
||||||
|
|
|
@ -71,10 +71,6 @@ should improve performance. The existing APIs were deprecated, and new APIs
|
||||||
were introduced, as described in the :doc:`transaction management docs
|
were introduced, as described in the :doc:`transaction management docs
|
||||||
</topics/db/transactions>`.
|
</topics/db/transactions>`.
|
||||||
|
|
||||||
Please review carefully the list of :ref:`known backwards-incompatibilities
|
|
||||||
<transactions-upgrading-from-1.5>` to determine if you need to make changes in
|
|
||||||
your code.
|
|
||||||
|
|
||||||
Persistent database connections
|
Persistent database connections
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -393,9 +389,7 @@ Behavior changes
|
||||||
|
|
||||||
Database-level autocommit is enabled by default in Django 1.6. While this
|
Database-level autocommit is enabled by default in Django 1.6. While this
|
||||||
doesn't change the general spirit of Django's transaction management, there
|
doesn't change the general spirit of Django's transaction management, there
|
||||||
are a few known backwards-incompatibilities, described in the :ref:`transaction
|
are a few backwards-incompatibilities.
|
||||||
management docs <transactions-upgrading-from-1.5>`. You should review your
|
|
||||||
code to determine if you're affected.
|
|
||||||
|
|
||||||
Savepoints and ``assertNumQueries``
|
Savepoints and ``assertNumQueries``
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -982,9 +976,6 @@ current APIs are deprecated:
|
||||||
- ``django.db.transaction.commit_manually``
|
- ``django.db.transaction.commit_manually``
|
||||||
- the ``TRANSACTIONS_MANAGED`` setting
|
- the ``TRANSACTIONS_MANAGED`` setting
|
||||||
|
|
||||||
The reasons for this change and the upgrade path are described in the
|
|
||||||
:ref:`transactions documentation <transactions-upgrading-from-1.5>`.
|
|
||||||
|
|
||||||
``django.contrib.comments``
|
``django.contrib.comments``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -502,222 +502,3 @@ transaction. For example::
|
||||||
|
|
||||||
In this example, ``a.save()`` will not be undone in the case where
|
In this example, ``a.save()`` will not be undone in the case where
|
||||||
``b.save()`` raises an exception.
|
``b.save()`` raises an exception.
|
||||||
|
|
||||||
.. _transactions-upgrading-from-1.5:
|
|
||||||
|
|
||||||
Changes from Django 1.5 and earlier
|
|
||||||
===================================
|
|
||||||
|
|
||||||
The features described below were deprecated in Django 1.6 and will be removed
|
|
||||||
in Django 1.8. They're documented in order to ease the migration to the new
|
|
||||||
transaction management APIs.
|
|
||||||
|
|
||||||
Legacy APIs
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The following functions, defined in ``django.db.transaction``, provided a way
|
|
||||||
to control transactions on a per-function or per-code-block basis. They could
|
|
||||||
be used as decorators or as context managers, and they accepted a ``using``
|
|
||||||
argument, exactly like :func:`atomic`.
|
|
||||||
|
|
||||||
.. function:: autocommit
|
|
||||||
|
|
||||||
Enable Django's default autocommit behavior.
|
|
||||||
|
|
||||||
Transactions will be committed as soon as you call ``model.save()``,
|
|
||||||
``model.delete()``, or any other function that writes to the database.
|
|
||||||
|
|
||||||
.. function:: commit_on_success
|
|
||||||
|
|
||||||
Use a single transaction for all the work done in a function.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. function:: commit_manually
|
|
||||||
|
|
||||||
Tells Django you'll be managing the transaction on your own.
|
|
||||||
|
|
||||||
Whether you are writing or simply reading from the database, you must
|
|
||||||
``commit()`` or ``rollback()`` explicitly or Django will raise a
|
|
||||||
:exc:`TransactionManagementError` exception. This is required when reading
|
|
||||||
from the database because ``SELECT`` statements may call functions which
|
|
||||||
modify tables, and thus it is impossible to know if any data has been
|
|
||||||
modified.
|
|
||||||
|
|
||||||
.. _transaction-states:
|
|
||||||
|
|
||||||
Transaction states
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The three functions described above relied on a concept called "transaction
|
|
||||||
states". This mechanism was deprecated in Django 1.6, but it's still available
|
|
||||||
until Django 1.8.
|
|
||||||
|
|
||||||
At any time, each database connection is in one of these two states:
|
|
||||||
|
|
||||||
- **auto mode**: autocommit is enabled;
|
|
||||||
- **managed mode**: autocommit is disabled.
|
|
||||||
|
|
||||||
Django starts in auto mode. ``TransactionMiddleware``,
|
|
||||||
:func:`commit_on_success` and :func:`commit_manually` activate managed mode;
|
|
||||||
:func:`autocommit` activates auto mode.
|
|
||||||
|
|
||||||
Internally, Django keeps a stack of states. Activations and deactivations must
|
|
||||||
be balanced.
|
|
||||||
|
|
||||||
For example, :func:`commit_on_success` switches to managed mode when entering
|
|
||||||
the block of code it controls; when exiting the block, it commits or
|
|
||||||
rollbacks, and switches back to auto mode.
|
|
||||||
|
|
||||||
So :func:`commit_on_success` really has two effects: it changes the
|
|
||||||
transaction state and it defines a transaction block. Nesting will give the
|
|
||||||
expected results in terms of transaction state, but not in terms of
|
|
||||||
transaction semantics. Most often, the inner block will commit, breaking the
|
|
||||||
atomicity of the outer block.
|
|
||||||
|
|
||||||
:func:`autocommit` and :func:`commit_manually` have similar limitations.
|
|
||||||
|
|
||||||
API changes
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Transaction middleware
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
In Django 1.6, ``TransactionMiddleware`` is deprecated and replaced by
|
|
||||||
:setting:`ATOMIC_REQUESTS <DATABASE-ATOMIC_REQUESTS>`. While the general
|
|
||||||
behavior is the same, there are two differences.
|
|
||||||
|
|
||||||
With the previous API, it was possible to switch to autocommit or to commit
|
|
||||||
explicitly anywhere inside a view. Since :setting:`ATOMIC_REQUESTS
|
|
||||||
<DATABASE-ATOMIC_REQUESTS>` relies on :func:`atomic` which enforces atomicity,
|
|
||||||
this isn't allowed any longer. However, at the top level, it's still possible
|
|
||||||
to avoid wrapping an entire view in a transaction. To achieve this, decorate
|
|
||||||
the view with :func:`non_atomic_requests` instead of :func:`autocommit`.
|
|
||||||
|
|
||||||
The transaction middleware applied not only to view functions, but also to
|
|
||||||
middleware modules that came after it. For instance, if you used the session
|
|
||||||
middleware after the transaction middleware, session creation was part of the
|
|
||||||
transaction. :setting:`ATOMIC_REQUESTS <DATABASE-ATOMIC_REQUESTS>` only
|
|
||||||
applies to the view itself.
|
|
||||||
|
|
||||||
Managing transactions
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Starting with Django 1.6, :func:`atomic` is the only supported API for
|
|
||||||
defining a transaction. Unlike the deprecated APIs, it's nestable and always
|
|
||||||
guarantees atomicity.
|
|
||||||
|
|
||||||
In most cases, it will be a drop-in replacement for :func:`commit_on_success`.
|
|
||||||
|
|
||||||
During the deprecation period, it's possible to use :func:`atomic` within
|
|
||||||
:func:`autocommit`, :func:`commit_on_success` or :func:`commit_manually`.
|
|
||||||
However, the reverse is forbidden, because nesting the old decorators /
|
|
||||||
context managers breaks atomicity.
|
|
||||||
|
|
||||||
Managing autocommit
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Django 1.6 introduces an explicit :ref:`API for managing autocommit
|
|
||||||
<managing-autocommit>`.
|
|
||||||
|
|
||||||
To disable autocommit temporarily, instead of::
|
|
||||||
|
|
||||||
with transaction.commit_manually():
|
|
||||||
# do stuff
|
|
||||||
|
|
||||||
you should now use::
|
|
||||||
|
|
||||||
transaction.set_autocommit(False)
|
|
||||||
try:
|
|
||||||
# do stuff
|
|
||||||
finally:
|
|
||||||
transaction.set_autocommit(True)
|
|
||||||
|
|
||||||
To enable autocommit temporarily, instead of::
|
|
||||||
|
|
||||||
with transaction.autocommit():
|
|
||||||
# do stuff
|
|
||||||
|
|
||||||
you should now use::
|
|
||||||
|
|
||||||
transaction.set_autocommit(True)
|
|
||||||
try:
|
|
||||||
# do stuff
|
|
||||||
finally:
|
|
||||||
transaction.set_autocommit(False)
|
|
||||||
|
|
||||||
Unless you're implementing a transaction management framework, you shouldn't
|
|
||||||
ever need to do this.
|
|
||||||
|
|
||||||
Disabling transaction management
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Instead of setting ``TRANSACTIONS_MANAGED = True``, set the ``AUTOCOMMIT`` key
|
|
||||||
to ``False`` in the configuration of each database, as explained in
|
|
||||||
:ref:`deactivate-transaction-management`.
|
|
||||||
|
|
||||||
Backwards incompatibilities
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
Since version 1.6, Django uses database-level autocommit in auto mode.
|
|
||||||
Previously, it implemented application-level autocommit by triggering a commit
|
|
||||||
after each ORM write.
|
|
||||||
|
|
||||||
As a consequence, each database query (for instance, an ORM read) started a
|
|
||||||
transaction that lasted until the next ORM write. Such "automatic
|
|
||||||
transactions" no longer exist in Django 1.6.
|
|
||||||
|
|
||||||
There are four known scenarios where this is backwards-incompatible.
|
|
||||||
|
|
||||||
Note that managed mode isn't affected at all. This section assumes auto mode.
|
|
||||||
See the :ref:`description of modes <transaction-states>` above.
|
|
||||||
|
|
||||||
Sequences of custom SQL queries
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If you're executing several :ref:`custom SQL queries <executing-custom-sql>`
|
|
||||||
in a row, each one now runs in its own transaction, instead of sharing the
|
|
||||||
same "automatic transaction". If you need to enforce atomicity, you must wrap
|
|
||||||
the sequence of queries in :func:`atomic`.
|
|
||||||
|
|
||||||
To check for this problem, look for calls to ``cursor.execute()``. They're
|
|
||||||
usually followed by a call to ``transaction.commit_unless_managed()``, which
|
|
||||||
isn't useful any more and should be removed.
|
|
||||||
|
|
||||||
Select for update
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If you were relying on "automatic transactions" to provide locking between
|
|
||||||
:meth:`~django.db.models.query.QuerySet.select_for_update` and a subsequent
|
|
||||||
write operation — an extremely fragile design, but nonetheless possible — you
|
|
||||||
must wrap the relevant code in :func:`atomic`. Since Django 1.6.3, executing
|
|
||||||
a query with :meth:`~django.db.models.query.QuerySet.select_for_update` in
|
|
||||||
autocommit mode will raise a
|
|
||||||
:exc:`~django.db.transaction.TransactionManagementError`.
|
|
||||||
|
|
||||||
Using a high isolation level
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If you were using the "repeatable read" isolation level or higher, and if you
|
|
||||||
relied on "automatic transactions" to guarantee consistency between successive
|
|
||||||
reads, the new behavior might be backwards-incompatible. To enforce
|
|
||||||
consistency, you must wrap such sequences in :func:`atomic`.
|
|
||||||
|
|
||||||
MySQL defaults to "repeatable read" and SQLite to "serializable"; they may be
|
|
||||||
affected by this problem.
|
|
||||||
|
|
||||||
At the "read committed" isolation level or lower, "automatic transactions"
|
|
||||||
have no effect on the semantics of any sequence of ORM operations.
|
|
||||||
|
|
||||||
PostgreSQL and Oracle default to "read committed" and aren't affected, unless
|
|
||||||
you changed the isolation level.
|
|
||||||
|
|
||||||
Using unsupported database features
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
With triggers, views, or functions, it's possible to make ORM reads result in
|
|
||||||
database modifications. Django 1.5 and earlier doesn't deal with this case and
|
|
||||||
it's theoretically possible to observe a different behavior after upgrading to
|
|
||||||
Django 1.6 or later. In doubt, use :func:`atomic` to enforce integrity.
|
|
||||||
|
|
Loading…
Reference in New Issue