Python应用级文档/记录锁定(例如,对于MongoDB)

时间:2013-11-22 22:16:57

标签: python multithreading mongodb locking

简介

MongoDB没有提供锁定文档的方法(比如RDBMS中的SELECT FOR UPDATE)。

Isolate Sequence of Operations的推荐方法,有时称为乐观锁定,但有些情况下这种方法似乎过于复杂甚至效率低(这就是为什么悲观锁仍在使用中。)

任务

我想在应用程序级别实现通用文档锁定。假设我只有一个应用程序处理集合。我的应用程序是多线程

使用场景:

with DocumentLock(doc_id):
  # make sure no other thread interferes
  doc=db.doc_collection.find_one(doc_id)
  ... # analyse and update the document
  db.doc_collection.save(doc)

问题

您会为此任务推荐什么解决方案?

1 个答案:

答案 0 :(得分:2)

这是我的DocumentLock类:

class DocumentLock(object):

  _lock=RLock() # protects access to _locks dictionary
  _locks=WeakValueDictionary()

  def __init__(self, doc_id):
    self.doc_id=doc_id

  def __enter__(self):
    with self._lock:
      self.lock=self._locks.get(self.doc_id)
      if self.lock is None:
        self._locks[self.doc_id]=self.lock=RLock()
    self.lock.acquire()

  def __exit__(self, exc_type, exc_value, traceback):
    self.lock.release()
    self.lock=None # make available for garbage collection

所以基本上我有一个RLocks字典,每个访问文档一个RLock。我使用弱引用来摆脱未使用的锁。

DocumentLock可以为需要记录锁定的每个集合(或表)进行子类化。

这一切似乎都有效(虽然没有在并发下进行测试),但我不确定这种方法是否存在缺陷,或者是否有更好的方法。