Ticket #9206: extra_v4.diff

File extra_v4.diff, 5.2 KB (added by Richard Davies <richard.davies@…>, 15 years ago)

Another new draft

  • docs/topics/db/transactions.txt

     
    150150all situations, you'll be better off using the default behavior, or the
    151151transaction middleware, and only modify selected functions as needed.
    152152
     153Savepoints
     154==========
     155
     156A savepoint is a marker within an open transaction that enables partial
     157rollback to the point when it was created.
     158
     159Under the default ``autocommit`` decorator this is not very useful, since
     160the open transaction is regularly committed in its entirety. However under
     161the ``commit_on_success`` or ``commit_manually`` the open transaction will
     162build up multiple database operations, so savepoints can provide more
     163fine-grained rollback than a full ``transaction.rollback()``. Example::
     164
     165    from django.db import transaction
     166
     167    @transaction.commit_manually
     168    def viewfunc(request):
     169
     170      a.save()
     171      # open transaction now contains a.save()
     172      sid = transaction.savepoint()
     173
     174      b.save()
     175      # open transaction now contains a.save() and b.save()
     176
     177      if want_to_keep_b:
     178        transaction.savepoint_commit(sid)
     179        # open transaction still contains a.save() and b.save()
     180
     181      else:
     182        transaction.savepoint_rollback(sid)
     183        # open transaction now contains only a.save()
     184
     185      transaction.commit()
     186
     187Savepoints are implemented in the PostgreSQL 8 and Oracle backends.
     188
    153189Transactions in MySQL
    154190=====================
    155191
     
    166202
    167203.. _information on MySQL transactions: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html
    168204
    169 Transactions and savepoints in PostgreSQL 8
    170 ===========================================
     205Database exceptions within PostgreSQL transactions
     206==================================================
    171207
    172 When a call to a PostgreSQL 8 cursor raises an exception, all subsequent SQL
    173 in the same transaction fails with the error "current transaction is aborted,
    174 queries ignored until end of transaction block". Whilst simple use of save()
    175 is unlikely to raise an exception in PostgreSQL, there are many more advanced
    176 usage patterns which might: for example, saving objects with unique fields,
    177 saving using the force_insert/force_update flag, or invoking custom SQL.
     208When a call to a PostgreSQL cursor raises an exception (typically
     209``IntegrityError``), all subsequent SQL in the same transaction fails with
     210the error "current transaction is aborted, queries ignored until end of
     211transaction block".  Whilst simple use of ``save()`` is unlikely to raise an
     212exception in PostgreSQL, there are many more advanced usage patterns which
     213might: for example, saving objects with unique fields, saving using the
     214force_insert/force_update flag, or invoking custom SQL.  Example::
    178215
    179 In any of these cases, you can wrap the command which may throw
    180 IntegrityError inside savepoints, which will then allow subsequent commands
    181 to proceed. Example::
     216    a.save() # succeeds
     217    try:
     218      b.save() # throws exception due to unique field
     219    except:
     220      pass
     221    c.save() # fails under PostgreSQL as current transaction is aborted
     222             # succeeds under all other database backends
    182223
     224There are three possible solutions to this issue, of which Django recommends
     225savepoint rollback:
     226
     227Transaction rollback
     228--------------------
     229
     230With any version of PostgreSQL, you can rollback to the start of the
     231transaction if you experience an exception. Example::
     232
     233    a.save() # succeeds, but may be undone by transaction rollback
    183234    try:
     235      b.save() # throws exception due to unique field
     236    except:
     237      transaction.rollback()
     238    c.save() # succeeds, but a.save() may have been undone
     239
     240Note that under the ``commit_on_success`` or ``commit_manually``
     241decorators the transaction rollback will also undo ``a.save()``.
     242
     243Savepoint rollback
     244------------------
     245
     246With PostgreSQL 8 or later, you can wrap just the command which may raise an
     247exception inside savepoints, isolating the rollback. Example::
     248
     249    a.save() # succeeds, and never undone by savepoint rollback
     250    try:
    184251      sid = transaction.savepoint()
    185       x.save()
     252      b.save() # throws exception due to unique field
    186253      transaction.savepoint_commit(sid)
    187     except IntegrityError:
     254    except:
    188255      transaction.savepoint_rollback(sid)
    189       raise
     256    c.save() # succeeds, and a.save() is never undone
    190257
    191 Savepoints are not implemented in PostgreSQL 7. If you experience an
    192 IntegrityError when using PostgreSQL 7, you will need to rollback to the
    193 start of the transaction.
     258Note that ``a.save()`` is never undone.
     259
     260Database-level autocommit
     261-------------------------
     262
     263.. versionadded:: 1.1
     264
     265With PostgreSQL 8.2 or later, there is an advanced option to run PostgreSQL
     266with :ref:`database-level autocommit <ref-databases>`. With this option
     267there is no constantly open transaction, so it is always possible to continue
     268after catching an exception. Please see the documentation for that feature,
     269which behaves differently from the standard ``autocommit`` decorator.
     270Example::
     271
     272    a.save() # succeeds
     273    try:
     274      b.save() # throws exception due to unique field
     275    except:
     276      pass
     277    c.save() # succeeds
Back to Top