Django的比赛条件
这是带有潜在竞争条件的Django视图的简单示例:
# myapp/views.pyfrom 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+支持select_for_update,在早期版本中,你可以执行原始SQL查询,例如select … forupdate
,取决于基础数据库,该行将锁定该行免受任何更新的影响,你可以对该行执行任何操作,直到事务结束。例如
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()
以上是 Django的比赛条件 的全部内容, 来源链接: utcz.com/qa/401830.html