Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
防止Django中重复的XMLHttpRequests_Django_Concurrency_Locking - Fatal编程技术网

防止Django中重复的XMLHttpRequests

防止Django中重复的XMLHttpRequests,django,concurrency,locking,Django,Concurrency,Locking,在我的应用程序中,单击按钮会向我的服务器发送XHR请求,以升级帐户并向用户收费 def upgradeView(request): if request.user.upgraded == False: billAccount(request.user.id) else: return HttpRequests('Already billed') request.user.upgraded = True request.user

在我的应用程序中,单击按钮会向我的服务器发送XHR请求,以升级帐户并向用户收费

def upgradeView(request):
    if request.user.upgraded == False:
         billAccount(request.user.id)
    else: 
         return HttpRequests('Already billed')
    request.user.upgraded = True
    request.user.save()
    return HttpResponse('OK!')
我可以使用Javascript更改按钮,以便在用户单击按钮一次后将其禁用。我如何才能在服务器端确认用户不能同时提交5个XHR请求,并最终获得5次账单?我有一个手动检查,检查他们是否已经计费,但是如果billAccount功能需要几秒钟,并且在用户能够被设置为升级之前,多个请求能够触发
billAccount
调用,该怎么办


我想得越多,就越不可能阻止多个请求滑入。即使billAccount调用为毫秒,也有足够的时间接收多个请求。

您可以添加另一个属性,该属性将在发送请求时设置为True,然后在发送响应之前设置为False。
根据该属性的值,您可以决定是否进行账单请求

def upgradeView(request):
   if request.user.bill_state == 'open':
      # So there is a biliing request is running and we
   else:
      # set bill state to true to prevent any further requests
      request.user.bill_state = 'open'
      request.user.save()

   # make normal process of billing here an before end the request
   request.user.bill_state = 'close'
   request.user.save()


我认为将变量从“打开”更改为“关闭”将比计费更快,并且可以防止多次请求。

答案是使用
select\u for\u update
transaction.atomic()
进行悲观锁定,并使用“no\u wait”参数。这样做的目的是防止任何其他进程在锁定对象时选择该对象。这是一个深入研究的巨大资源

以下是我认为您可以锁定行的方式,这样多个事务就不会同时发生:

def upgradeView(request):
    with transaction.atomic():
        u = Users.objects.select_for_update(nowait=True).filter(pk=request.user.pk)
        if u.upgraded == False:
             billAccount(u.id)
        else: 
             return HttpRequests('Already billed')
        u.upgraded = True
        u.save()
        return HttpResponse('OK!')