防止 Django 中重复的 XMLHttpRequests
Preventing duplicate XMLHttpRequests in Django
在我的应用程序中,单击按钮会向我的服务器发送 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()
我认为将变量从 'open' 更改为 'close' 会比计费更快,而且您可以防止多次请求。
答案是使用 select_for_update
和 transaction.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!')
在我的应用程序中,单击按钮会向我的服务器发送 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()
我认为将变量从 'open' 更改为 'close' 会比计费更快,而且您可以防止多次请求。
答案是使用 select_for_update
和 transaction.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!')