django - 在 Django 中防止重复的 XMLHttpRequests
问题描述
在我的应用程序中,单击按钮会向我的服务器发送 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
调用是一毫秒,这仍然足够多个请求进来的时间。
解决方案
答案是使用select_for_update
和transaction.atomic()
用于悲观锁定,以及“no_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!')
推荐阅读
- wordpress - WordPress插件可以应用到博客吗?
- php - 在测试环境中,php文件根本不呈现的问题
- javascript - only first value is changed when iterating through express-handlebars each
- javascript - 如果字段不为空,请勿在提交时验证 Formik 和 Yup 中未触及的字段
- javascript - audio play/pause button problem in multiline
- css - 转换持续时间在 Firefox 中不起作用
- oracle - How can I properly reference the database link name in the below procedure
- java - 关闭 Google Pub 子发布商时出错
- javascript - 使用来自 AJAX 网站的 selenium 和 beautifulsoup 在 python 中抓取图像
- php - 获取第n级多维数组PHP中的键值