# /uri/one/{pk}/
class ModelOneView(generic.View):
def post(self, request, pk): # pk has the same value as below
Model.objects.filter(pk=pk).update(name=request.POST['name'])
return HttpResponse(status=200)
# /uri/two/{pk}/
class ModelTwoView(generic.View):
def post(self, request, pk): # pk has the same value as above
Model.objects.filter(pk=pk).update(bool_field=True)
return HttpResponse(status=200)
我简化了我的代码,但基本上我正在做的是我有两个不同的URI,它们都在同一个模型上执行一些更改(尽管不是同一个字段)。 这里的问题是我的客户基本上同时打电话给他们。
// script.js in my index.html
function notHealthyForDjango() {
callFirstURI();
callSecondURI();
}
Django和Client都不会在任何时候抛出任何错误,我收到OK回复。但是,我试图用callFirstURI()进行更改;永远不会到达数据库。但是当我注释掉callSecondURI();
时function notHealthyForDjango() {
callFirstURI();
//callSecondURI();
}
现在对第一个URI的调用按预期工作!
我该如何解决这个问题?我正在使用psql,Python 2.7和Django 1.9。 如何在不存在此类碰撞风险的情况下修改模型字段?
修改
我想找到解决问题的服务器端解决方案,而不是仅仅更好地计算客户端的javascript请求。
答案 0 :(得分:1)
您考虑过select_for_update吗?
返回一个将锁定行直到结束的查询集 事务,生成一个SELECT ... FOR UPDATE SQL语句 支持的数据库。
支持的数据库是Postgresql,Oracle和Mysql。我注意到你还没有提到你的数据库。虽然sqlite不受支持,但它至少在linux上很少出现问题,因为文件锁定会确保相同的数据不会被sqlite写下来。
您需要将此与原子事务一起使用才能获得最佳效果。
def post(self, request, pk): # pk has the same value as below
with transaction.atomic():
Model.objects.select_for_update().filter(pk=pk).update(
name=request.POST['name'])
return HttpResponse(status=200)
答案 1 :(得分:0)
您可能想尝试两个建议:
使用AJAX请求中的回调完成callSecondURI()
后运行callFirstURI()
它可能不适用(我绝不是这方面的专家),但这听起来好像可能与多线程有关。请看this question处理此问题的装饰工具。