下面是一个带有潜在竞争条件的 django 视图的简单示例:
# myapp/views.py
from django.contrib.auth.models import User
from my_libs import calculate_points
def add_points(request):
user = request.user
user.points += calculate_points(user)
user.save()
竞争条件应该相当明显:用户可以发出此请求两次,并且应用程序可能会执行user = request.user
同时,导致一个请求覆盖另一个请求。
假设函数calculate_points
比较复杂,并且基于各种奇怪的东西进行计算,不能放在一个单一的东西中update
并且很难放入存储过程中。
所以这是我的问题:django 可以使用什么样的锁定机制来处理类似的情况?
Django 1.4+ 支持选择更新 https://docs.djangoproject.com/en/stable/ref/models/querysets/#django.db.models.query.QuerySet.select_for_update,在早期版本中,您可以执行原始 SQL 查询,例如select ... for update
根据底层数据库的不同,该行将锁定该行以防止任何更新,您可以对该行执行任何操作,直到事务结束。例如
from django.db import transaction
@transaction.commit_manually()
def add_points(request):
user = User.objects.select_for_update().get(id=request.user.id)
# you can go back at this point if something is not right
if user.points > 1000:
# too many points
return
user.points += calculate_points(user)
user.save()
transaction.commit()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)