Python web框架中的工作同步,即Django

Python web框架中的工作同步,即Django,python,django,multithreading,synchronization,Python,Django,Multithreading,Synchronization,尽管与此类问题相关的可能工具的范围很广,但我们正在使用Django 在我们感兴趣的系统中,我们使用两种工人gunicorn工作人员负责提供django视图,Cellery负责一些应异步执行的例程。这两种类型的工作者都可以从数据库中读/写,因此在下文中,他们将被简单地称为工作者 可以按如下方式执行数据库操作: >>> from someapp.models import mymodel >>> foo = mymodel(field1='bar', fiel

尽管与此类问题相关的可能工具的范围很广,但我们正在使用Django

在我们感兴趣的系统中,我们使用两种工人
gunicorn
工作人员负责提供django视图,
Cellery
负责一些应异步执行的例程。这两种类型的工作者都可以从数据库中读/写,因此在下文中,他们将被简单地称为
工作者

可以按如下方式执行数据库操作:

>>> from someapp.models import mymodel 

>>> foo = mymodel(field1='bar', field2='baz')
>>> foo.save()
>>> foo.id
5
假设它存在于数据库中,您也可以得到相同的
foo
对象,如下所示:

>>> foo = mymodels.objects.get(id=5)
>>> foo.field1
'bar'
让我们做一个案例研究

有2名工人在系统上操作,同时他们在
mymodel

# Both processes
foo = mymodel.objects.get(id=5)
然后,工人1将
field1
更改为
'bird'

# Worker 1
foo.field1 = 'bird'
工作者2将
field2
更改为
“恐龙”

# Worker 2
foo.field2 = 'dinosaur'
此时,不会向数据库写入任何内容。如果

# Worker 1
foo.save()
相关行更改为:

 id  |  field1 | field2  
-----+---------+------
 5   |  bird   | baz
此操作后,如果

# Worker 2
foo.save()
发生这种情况:

 id  |  field1 | field2  
-----+---------+------
 5   |   bar   | dinosaur
正如您所同意的,这是一个严重的同步问题。有没有优雅的方法来解决这个问题?我应该如何进行


有一点是,这个问题太明显了,但我在互联网上从未见过任何地方提到我在这里描述的内容,这让我对这个问题的有效性产生了一些怀疑。

您可以使用“更新字段”属性来指定要保存的字段

foo.save(更新_字段=['field2'])

UPD。。。 或使用应用程序进行乐观并发控制:


django并发性

如果每个工作进程只更新特定字段,建议使用crash843的答案

如果您希望每个工作人员在快速修改之前抓取一行并锁定它,请使用
选择\u for\u update()

在当前Django事务退出之前,条目将被锁定

参考:

entries = Entry.objects.select_for_update().filter(author=request.user)