From 5d8342f321c1e1017e63555270999c9378f10185 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Wed, 13 Mar 2013 14:47:48 +0100 Subject: [PATCH] Proof-read and adjusted the transactions docs. --- docs/internals/deprecation.txt | 14 ++++--- docs/releases/1.6.txt | 3 +- docs/topics/db/transactions.txt | 70 +++++++++++++++------------------ 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index b9948affcb..1305d68859 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -329,14 +329,19 @@ these changes. 1.8 --- +* ``django.contrib.comments`` will be removed. + * The following transaction management APIs will be removed: - ``TransactionMiddleware``, - 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. - Upgrade paths are described in :ref:`transactions-upgrading-from-1.5`. + Upgrade paths are described in the :ref:`transaction management docs + `. * 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 @@ -358,14 +363,11 @@ these changes. ``ChangeList.root_query_set`` and ``ChangeList.query_set``. * The following private APIs will be removed: + - ``django.db.close_connection()`` - ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()`` - ``django.db.transaction.is_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 --- diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index eec55c6632..30c3cc5d2c 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -36,7 +36,8 @@ Improved transaction management Django's transaction management was overhauled. Database-level autocommit is now turned on by default. This makes transaction handling more explicit and 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 +`. Please review carefully the list of :ref:`known backwards-incompatibilities ` to determine if you need to make changes in diff --git a/docs/topics/db/transactions.txt b/docs/topics/db/transactions.txt index 122af14359..697dee49c0 100644 --- a/docs/topics/db/transactions.txt +++ b/docs/topics/db/transactions.txt @@ -35,10 +35,10 @@ transaction. Set :setting:`ATOMIC_REQUESTS ` to ``True`` in the configuration of each database for which you want to enable this behavior. -It works like this. When a request starts, Django starts a transaction. If the -response is produced without problems, Django commits the transaction. If the -view function produces an exception, Django rolls back the transaction. -Middleware always runs outside of this transaction. +It works like this. Before calling a view function, Django starts a +transaction. If the response is produced without problems, Django commits the +transaction. If the view produces an exception, Django rolls back the +transaction. 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 @@ -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 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: Deactivating transaction management @@ -251,8 +244,8 @@ Autocommit .. versionadded:: 1.6 -Django provides a straightforward API to manage the autocommit state of each -database connection, if you need to. +Django provides a straightforward API in the :mod:`django.db.transaction` +module to manage the autocommit state of each database connection. .. 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 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) @@ -332,10 +325,8 @@ Savepoints are controlled by three functions in :mod:`django.db.transaction`: .. function:: 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``). + 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``). .. 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. 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``, -``DELETE`` and ``REPLACE``.) - -This has two consequences: +``DELETE`` and ``REPLACE``.) This bug has two consequences: - The low level APIs for savepoints are only usable inside a transaction ie. 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 `information on MySQL transactions`_. -If your MySQL setup does *not* support transactions, then Django will function -in autocommit 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. +If your MySQL setup does *not* support transactions, then Django will always +function in autocommit 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 +.. note:: + This section is relevant only if you're implementing your own transaction + management. This problem cannot occur in Django's default mode and + :func:`atomic` handles it automatically. + +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. 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 be balanced. -For example, ``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. +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 an transaction block. Nesting will give the @@ -568,7 +562,7 @@ you must now use this pattern:: my_view.transactions_per_request = False 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 transaction. :setting:`ATOMIC_REQUESTS ` only 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`. 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 necessary any more and should be removed. +usually followed by a call to ``transaction.commit_unless_managed()``, which +isn't useful any more and should be removed. Select for update ~~~~~~~~~~~~~~~~~