Django的比赛条件

这是带有潜在竞争条件的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+支持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

回到顶部