Django select_for_update不能在事务外部使用

Django select_for_update不能在事务外部使用,django,transactions,django-1.5,django-1.6,Django,Transactions,Django 1.5,Django 1.6,我使用的是Django 1.5.1并升级到Django 1.6.6 在Django 1.5.1中,我使用select for update来保证原子执行 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/

我使用的是Django 1.5.1并升级到Django 1.6.6

在Django 1.5.1中,我使用select for update来保证原子执行

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.

解决此问题的一些解决方案是什么?

答案是错误,将查询包装到事务中

Django的文档位于以下位置:

一种方法是:

from django.db import transaction

def some_method():    
   with transaction.atomic():
      job_qs = Job.objects.select_for_update().filter(pk=job.id)
      for job in job_qs:
补遗 从Django 2.0开始,默认情况下会锁定相关行(不确定之前的行为是什么),并且可以使用参数的
以与
选择相关的
相同的样式指定要锁定的行:

默认情况下,
select\u for\u update()
锁定查询选择的所有行。例如,
select\u related()
中指定的相关对象行,除了queryset的模型行之外,还被锁定。如果不需要,请使用与
select\u related()
相同的字段语法指定要锁定的相关对象。使用值“self”引用queryset的模型


对我来说,即使对transaction.atomic()使用
时也会发生这种情况。问题是我们没有在
settings.py
文件中设置
“原子请求”:True
。现在这个问题解决了

如本文所述:

“在要启用此行为的每个数据库的配置中,将
ATOMIC_REQUESTS
设置为
True
。”

因此,在
settings.py
中,我们添加了:

数据库={
“默认值”:{
'ENGINE':'django.db.backends.mysql',
'NAME':os.environ['DB_NAME'],
“用户”:os.environ['DB_USER'],
“密码”:os.environ['DB_PASSWORD'],
'HOST':os.environ['DB_HOST'],
“端口”:“3306”,
“原子请求”:True
}
}

如果作业有外键,表相关是否也被锁定?通常为数据库更新选择锁定特定表/行,而不是相关行。这不仅会更改特定代码段,还会更改所有数据库行为。