Django select_for_update不能在事务外部使用
我使用的是Django 1.5.1并升级到Django 1.6.6 在Django 1.5.1中,我使用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/
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
}
}
如果作业有外键,表相关是否也被锁定?通常为数据库更新选择锁定特定表/行,而不是相关行。这不仅会更改特定代码段,还会更改所有数据库行为。