我用的是Django 1.5.1,升级到了Django 1.6.6。
在Django1.5.1中,我使用select来更新,以保证原子执行。
# "views.py"
from django.db import transaction
def some_method():
job_qs = Job.objects.select_for_update().filter(pk=job.id)
for job in job_qs:
不幸的是,现在抛出了一个错误:
File "/srv/venvs/django-picdoc/local/lib/python2.7/site-packages/django/db/models/query.py", line 96, in __iter__
self._fetch_all()
File "/srv/venvs/django-picdoc/local/lib/python2.7/site-packages/django/db/models/query.py", line 857, in _fetch_all
self._result_cache = list(self.iterator())
File "/srv/venvs/django-picdoc/local/lib/python2.7/site-packages/django/db/models/query.py", line 220, in iterator
for row in compiler.results_iter():
File "/srv/venvs/django-picdoc/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 713, in results_iter
for rows in self.execute_sql(MULTI):
File "/srv/venvs/django-picdoc/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 776, in execute_sql
sql, params = self.as_sql()
File "/srv/venvs/django-picdoc/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 147, in as_sql
raise TransactionManagementError("select_for_update cannot be used outside of a transaction.")
TransactionManagementError: select_for_update cannot be used outside of a transaction.
有哪些解决方案可以解决这个问题?
4条答案
按热度按时间relj7zay1#
答案在错误中,请将查询 Package 在事务中
Django的文档位于:https://docs.djangoproject.com/en/dev/topics/db/transactions/#django.db.transaction.atomic
一种方法是:
oyxsuwqo2#
附录
从Django 2.0开始,相关的行默认被锁定(不确定之前的行为是什么),要锁定的行可以使用
of
参数以select_related
相同的样式指定:默认情况下,
select_for_update()
会锁定查询所选的所有行。例如,除了查询集模型的行之外,select_related()
中指定的相关对象的行也会被锁定。如果不需要这样做,请使用与select_related()
相同的字段语法在select_for_update(of=(...))
中指定要锁定的相关对象。使用值"self"引用查询集模型。https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-for-update
ocebsuys3#
select_for_update()
必须在事务中运行。因此,对视图使用**
@transaction.atomic
**,如下所示:或者,在视图中使用**
with transaction.atomic():
**,如下所示:或者,将**
'ATOMIC_REQUESTS': True
设置为settings.py
中的数据库设置**,如下所示:watbbzwu4#
对我来说,即使在使用
with transaction.atomic():
时也会发生这种情况。问题是我们没有在settings.py
文件中设置'ATOMIC_REQUESTS': True
。现在这解决了问题。如下所示:https://docs.djangoproject.com/en/3.1/topics/db/transactions/
"在要启用此行为的每个数据库的配置中,将
ATOMIC_REQUESTS
设置为True
。"因此在
settings.py
中我们添加了: