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)
您会为此任务推荐什么解决方案?
答案 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可以为需要记录锁定的每个集合(或表)进行子类化。
这一切似乎都有效(虽然没有在并发下进行测试),但我不确定这种方法是否存在缺陷,或者是否有更好的方法。