防止Django中重复的XMLHttpRequests
在我的应用程序中,单击按钮会向我的服务器发送XHR请求,以升级帐户并向用户收费防止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
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!')