gpt4 book ai didi

python - 避免并发访问同一个队列元素

转载 作者:太空宇宙 更新时间:2023-11-03 13:30:46 24 4
gpt4 key购买 nike

我正在审查/重构一个将由最多 20 人同时在内部使用的队列,但截至目前,多个人可以访问第一个元素(我们尝试在本地同时单击链接。)

通量类似这样:

views.py

[GET]
def list_operator(request, id):
if request.POST:
utilitary = Utilitary(id)
pool = ThreadPool(processes=1)
async_result = pool.apply_async(utilitary.recover_people, (id, ))
return_val = async_result.get()
person = People.objects.get(pk=return_val)
return redirect('people:people_update', person.pk)

utilitary.py

此文件具有方法 recover_people,它在多个表中执行大约 4-5 个查询(其中人们有 flag_allocated=False)并对列表进行排序,以返回第一个元素。最后一步是:

for person in people:
p_address = People_Address.objects.get(person_id=person.id)
p_schedule = Schedules.objects.get(schedules_state=p_address.p_state)

if datetime.now() > parse_time(p_schedule.schedules_hour):
person = People.objects.get(pk=person.id)
person.flag_allocated = True
person.date_of_allocation = datetime.now()
person.save()
return person.pk

也许 Utilitary 方法的逻辑有问题?或者我应该预料到这么多人同时调用这个方法会出现这个问题?

使用缓存有帮助吗?对不起,我是 django 和 mvc 的新手。

最佳答案

在这种情况下,再次选择数据库中的“人”只是为了将其锁定在内存中,然后将其写入数据库似乎很多。此操作不是原子操作。

您可以在这些操作之间让其他进程锁定记录:

person = People.objects.get(pk=person.id)
person.flag_allocated = True
person.date_of_allocation = datetime.now()
person.save()

这就是你的问题所在。但是...如果您直接更新数据库上的记录并传递一个条件,在该条件下更新只会写入 flag_allocated=False 的记录,您只需要查看您的更新是否影响任何行或不。如果没有,您将转到队列中的下一个人。

类似于:

for person in people:
rows = People.objects.filter(pk=person.id, flag_allocated=False).update(flag_allocated=True)
if rows:
break # Got the person... And nobody else will.

更新会将记录锁定写入allocation_flag(SQL原理)。如果两个更新试图弄乱同一行,一个会先做,然后第二个不会更新任何东西,并会尝试下一个人。

关于python - 避免并发访问同一个队列元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47775567/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com