Fixed #22491 -- documented how select_for_update() should be tested.
Thanks Andreas Pelme for the report.
This commit is contained in:
parent
0af593dbe5
commit
668d432d0a
|
@ -1415,17 +1415,18 @@ backends support ``select_for_update()``. However, MySQL has no support for the
|
|||
``nowait`` argument. Obviously, users of external third-party backends should
|
||||
check with their backend's documentation for specifics in those cases.
|
||||
|
||||
Passing ``nowait=True`` to ``select_for_update`` using database backends that
|
||||
Passing ``nowait=True`` to ``select_for_update()`` using database backends that
|
||||
do not support ``nowait``, such as MySQL, will cause a
|
||||
:exc:`~django.db.DatabaseError` to be raised. This is in order to prevent code
|
||||
unexpectedly blocking.
|
||||
|
||||
Evaluating a queryset with ``select_for_update`` in autocommit mode is
|
||||
an error because the rows are then not locked. If allowed, this would
|
||||
facilitate data corruption, and could easily be caused by calling,
|
||||
outside of any transaction, code that expects to be run in one.
|
||||
Evaluating a queryset with ``select_for_update()`` in autocommit mode is
|
||||
a :exc:`~django.db.transaction.TransactionManagementError` error because the
|
||||
rows are not locked in that case. If allowed, this would facilitate data
|
||||
corruption and could easily be caused by calling code that expects to be run in
|
||||
a transaction outside of one.
|
||||
|
||||
Using ``select_for_update`` on backends which do not support
|
||||
Using ``select_for_update()`` on backends which do not support
|
||||
``SELECT ... FOR UPDATE`` (such as SQLite) will have no effect.
|
||||
|
||||
.. versionchanged:: 1.6.3
|
||||
|
@ -1433,6 +1434,16 @@ Using ``select_for_update`` on backends which do not support
|
|||
It is now an error to execute a query with ``select_for_update()`` in
|
||||
autocommit mode. With earlier releases in the 1.6 series it was a no-op.
|
||||
|
||||
.. warning::
|
||||
|
||||
Although ``select_for_update()`` normally fails in autocommit mode, since
|
||||
:class:`~django.test.TestCase` automatically wraps each test in a
|
||||
transaction, calling ``select_for_update()`` in a ``TestCase`` even outside
|
||||
an :func:`~django.db.transaction.atomic()` block will (perhaps unexpectedly)
|
||||
pass without raising a ``TransactionManagementError``. To properly test
|
||||
``select_for_update()`` you should use
|
||||
:class:`~django.test.TransactionTestCase`.
|
||||
|
||||
raw
|
||||
~~~
|
||||
|
||||
|
|
|
@ -636,7 +636,10 @@ to test the effects of commit and rollback:
|
|||
While ``commit`` and ``rollback`` operations still *appear* to work when
|
||||
used in ``TestCase``, no actual commit or rollback will be performed by the
|
||||
database. This can cause your tests to pass or fail unexpectedly. Always
|
||||
use ``TransactionTestCase`` when testing transactional behavior.
|
||||
use ``TransactionTestCase`` when testing transactional behavior or any code
|
||||
that can't normally be excuted in autocommit mode
|
||||
(:meth:`~django.db.models.query.QuerySet.select_for_update()` is an
|
||||
example).
|
||||
|
||||
``TransactionTestCase`` inherits from :class:`~django.test.SimpleTestCase`.
|
||||
|
||||
|
|
Loading…
Reference in New Issue