我去香蕉吧。我试图实现并发保护。
所以我发现有两种方法可以做到这一点。 乐观 - 基本上我们在记录中添加一个版本字段,每次保存都会增加它。因此,如果我当前的版本字段与光盘上的版本字段不同,则意味着某些内容已被修改,我会给出错误。
悲观的方法意味着我们只是锁定一条记录而且无法编辑。
我为Django实现了两种方式加上并发包,没有任何方法可以在SQLLite和Postgres上使用Heroku。
以下是我的查看方法,它有两种方法
对于悲观,我使用select_for_update锁定事务原子 为了乐观,我使用并发django包,在每次编辑时增加我的版本字段并与on_disc值进行简单比较
我做错了什么?请帮帮忙?
@login_required
def lease_edit(request,pk,uri):
logger = logging.getLogger(__name__)
title = 'Edit Lease'
uri = _get_redirect_url(request, uri)
with transaction.atomic():
post = get_object_or_404(Lease.objects.select_for_update(), pk=pk)
if request.method == "POST":
form = LeaseForm(request.POST, instance=post)
if form.is_valid():
lease = form.save(commit=False)
on_disc= Lease.objects.get(pk=post.id)
if on_disc.version > post.version:
messages.add_message(request, messages.ERROR, str(lease.id) + "-Error object was modified by another user. Please reopen object.")
return redirect(uri)
lease.save()
messages.add_message(request, messages.SUCCESS, str(lease.id) + "--SUCCESS Object saved successfully")
return redirect(uri)
else:
form = LeaseForm(instance=post)
#lease = post.lease
return render(request, 'object_edit.html', {'form': form, 'title':title, 'extend': EXTEND})
要测试我只打开2个具有相同记录的浏览器并尝试并行编辑(我使用相同的用户)
答案 0 :(得分:0)
问题在于网站的运作方式。目前您的锁定工作方式如下:
此处没有任何内容可以阻止行。多个实例可以将数据发送到服务器,因为在每个请求之后行被解锁。这是Web系统通常工作的方式,每个请求都是独立的,锁定必须以不同方式完成。
对于行版本控制,如果我正确理解了代码,您不会将当前行号发送到浏览器,但是在更新时会读取它。这再次意味着您获得了正确的数字。您应该将当前号码发送到浏览器,并在POST时将该号码与数据库中的当前号码进行比较。这样,如果有什么变化,就会检测到它。
由于我不熟悉Django,我可能错了这部分,但这是我对代码功能的理解。我认为form
可能有当前行版本,但它没有与任何东西进行比较,只有数据库中的当前数字和更新后的数字(可能也可能更改数字)。