Django模型中的并发控制 [英] Concurrency control in Django model

查看:238
本文介绍了Django模型中的并发控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何处理Django模型中的并发?我不想让读取相同记录的其他用户覆盖记录的更改

解决方案

简短的答案,这真的是提出的Django问题。



并发控制通常表现为技术问题,但在许多方面是功能需求的问题。你想要/需要你的应用程序工作吗?直到我们知道,这将很难给出任何Django的具体建议。



但是,我觉得漫漫,所以这里...



我有两个问题在遇到需要并发控制时问自己:




  • 两位用户需要同时修改同一条记录的可能性有多大?

  • 如果他/她对记录的修改丢失,对用户有什么影响?



如果碰撞的可能性相对较高,或者失去修改的影响是严重的,那么您可能会看到某种形式悲观的锁定。在一个悲观的计划中,每个用户必须先获得一个逻辑锁,才能打开记录进行修改。



悲观锁定具有很大的复杂性。您必须同步对锁的访问,考虑容错,锁定到期,超级用户可以锁定锁定,用户可以看到谁拥有锁,等等。



在Django中,可以使用单独的锁定模型或锁定记录上的某种锁定用户外键实现。使用锁定表可以让您在存储锁定时获得更多的灵活性,用户,笔记等。如果您需要一个可用于锁定任何种类的记录的通用锁表,请查看 django.contrib.contenttypes框架,但很快就可以转化为抽象宇航员综合征。



如果碰撞不太可能或丢失的修改被简单地重新创建,那么您可以在功能上消除乐观的并发技术。这种技术简单易用。基本上,您只需跟踪版本号或修改时间戳,并拒绝您检测到的任何修改,以免发生错误。



从功能设计的角度来看,您只有考虑如何将这些并发修改错误提供给您的用户。



在Django方面,乐观并发控制可以通过覆盖您的模型类的保存方法来实现。

  def save(self,* args,** kwargs):
if self.version!= self。 read_current_version():
raise ConcurrentModificationError('Ooops !!!!')
super(MyModel,self).save(* args,** kwargs)
当然,对于这些并发机制中的任何一个来说都是稳健的,你必须考虑事务控制。如果您不能保证交易的ACID属性,这两个模型都不可行。


How do I handle concurrency in a Django model? I dont want the changes to the record being overwritten by another user who reads the same record

解决方案

The short answer, this really isn't a Django question as presented.

Concurrency control is often presented as a technical question, but is in many ways a question of functional requirements. How do you want/need your application to work? Until we know that, it will be difficult to give any Django-specific advice.

But, I feel like rambling, so here goes...

There are two questions that I tend to ask myself when confronted with the need for concurrency control:

  • How likely is it that two users will need to concurrently modify the same record?
  • What is the impact to the user if his/her modifications to a record are lost?

If the likelihood of collisions is relatively high, or the impact of losing a modification is severe, then you may be looking at some form of pessimistic locking. In a pessimistic scheme, each user must acquire a logical lock prior to opening the record for modification.

Pessimistic locking comes with much complexity. You must synchronize access to the locks, consider fault tolerance, lock expiration, can locks be overridden by super users, can users see who has the lock, so on and so on.

In Django, this could be implemented with a separate Lock model or some kind of 'lock user' foreign key on the locked record. Using a lock table gives you a bit more flexibility in terms of storing when the lock was acquired, user, notes, etc. If you need a generic lock table that can be used to lock any kind of record, then take a look at the django.contrib.contenttypes framework, but quickly this can devolve into abstraction astronaut syndrome.

If collisions are unlikely or lost modifications are trivially recreated, then you can functionally get away with optimistic concurrency techniques. This technique is simple and easier to implement. Essentially, you just keep track of a version number or modification time stamp and reject any modifications that you detect as out of whack.

From a functional design standpoint, you only have to consider how these concurrent modification errors are presented to your users.

In terms of Django, optimistic concurrency control can be implemented by overriding the save method on your model class...

def save(self, *args, **kwargs):
    if self.version != self.read_current_version():
        raise ConcurrentModificationError('Ooops!!!!')
    super(MyModel, self).save(*args, **kwargs)

And, of course, for either of these concurrency mechanisms to be robust, you have to consider transactional control. Neither of these models are fully workable if you can't guarantee ACID properties of your transactions.

这篇关于Django模型中的并发控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆