【问题标题】:Preventing duplicate XMLHttpRequests in Django在 Django 中防止重复的 XMLHttpRequests
【发布时间】:2020-08-29 04:36:30
【问题描述】:

在我的应用中,单击按钮会向我的服务器发送 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调用是一毫秒,这仍然足够多个请求进来的时间。

【问题讨论】:

    标签: django concurrency locking


    【解决方案1】:

    您可以添加另一个属性,该属性将在发送请求时设置为 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()
    
    

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

    【讨论】:

      【解决方案2】:

      答案是使用select_for_updatetransaction.atomic() 进行悲观锁定,以及“no_wait”参数。这样做是为了防止任何其他进程在该对象被锁定时选择该对象。 Here's 一个更深入的好资源。

      我认为您可以通过以下方式锁定该行,以免多个事务同时发生:

      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!')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多