You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Django视图临时成为单例?解决重复点击超额加钱问题

解决Django视图钱包并发超额问题

这个问题是典型的并发竞态条件:当用户快速重复点击按钮时,多个请求会同时读取到用户钱包的旧余额,各自计算需要添加的金额后执行保存操作,最终导致钱包余额超过10美元的上限。不用修改模型或引入外部包,仅通过调整视图逻辑就能解决,核心是用Django的行级锁来避免并发冲突。

函数视图修复方案

我们需要利用select_for_update锁定用户数据行,确保同一时间只有一个请求能修改用户余额,同时在事务内完成操作保证原子性:

from django.db import transaction
from django.contrib.auth.models import User
from django.http import HttpResponse

def my_view(request):
    # 开启原子事务,确保锁定和修改操作的完整性
    with transaction.atomic():
        # 重新查询并锁定当前用户对象,避免使用request.user(已缓存旧数据)
        user = User.objects.select_for_update().get(id=request.user.id)
        # 计算需要添加的金额(基于锁定后的最新余额)
        money_needed = 10 - user.money
        if money_needed > 0:
            # 直接一次性加到上限,替代原有的循环累加(更高效且减少冲突)
            user.money += money_needed
            user.save()
    return HttpResponse("Ok!")

关键修复点说明

  • select_for_update():会在数据库层面锁定查询到的用户行,其他请求必须等待当前事务提交后才能读取该用户数据,彻底避免并发读取旧值的问题。
  • transaction.atomic():包裹整个操作,确保锁定和修改是原子性的,要么全部完成,要么全部回滚,避免中间状态引发的异常。
  • 重新查询用户:不能直接使用request.user,因为它是请求初始化时缓存的旧数据,没有被锁定,必须通过带锁的查询获取最新的用户对象。
  • 移除循环累加:原代码的循环每次加1都执行save(),既低效又增加了冲突概率,直接一次性加到上限更合理。

类视图替代方案

如果更倾向于使用类视图,可以基于UpdateView实现,同样利用行级锁:

from django.db import transaction
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import UpdateView
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect

class WalletTopUpView(LoginRequiredMixin, UpdateView):
    model = User
    fields = ['money']

    def get_object(self, queryset=None):
        # 在获取对象时锁定用户行
        with transaction.atomic():
            return User.objects.select_for_update().get(id=self.request.user.id)

    def form_valid(self, form):
        user = self.get_object()
        money_needed = 10 - user.money
        if money_needed > 0:
            user.money += money_needed
            user.save()
        # 重定向回原页面(或其他指定页面)
        return HttpResponseRedirect(self.request.path)

内容的提问来源于stack exchange,提问作者Manuel Fedele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:34:30