Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Introduction

MongoDB does not provide means to lock a document (like SELECT FOR UPDATE in RDBMS).

There is recommended approach to Isolate Sequence of Operations, which is sometimes called optimistic locking, but there are scenarios when this approach seems to be overly complicated or even inefficient (that is why pessimistic locks are still in use).

Task

I am trying to implement generic (can be used with various databases) document (or record) locking at application level. Assuming I have only one application working with collection (or table). And my application is multi-threaded.

Usage scenario:

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)

Solution

Here is my DocumentLock class:

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

So basically I have a dictionary of RLocks, one RLock per accessed document. I use weak references to get rid of unused locks.

DocumentLock can be subclassed for every collection (or table) that needs record locking.

Question

This all seems to work (although not tested under concurrency) but I am publishing it here for review and advise. Do you see any weaknesses or mistakes in this code? Is there a better approach to do this kind of things in Python?

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.