2012-07-16 79 views
2

我使用的Web应用程序pymongo,和想要做的形式的东西锁定一个文件:MongoDB中

doc = collection.find(document) 
doc.array1.append('foo') 
for(y in doc.array2): <do things with y> 
doc.array2 = filter(lambda x: ..., doc.array2) 
doc.x = len(doc.array2) 
collection.save(doc) 

有没有什么简单的方法,这样我可以处理处理同一文档的多个请求并防止他人破坏另一个/的结果无效,因为它正在编辑一个陈旧的版本?

回答

2

看看在MongoDB的文档的部分上Atomic Operations

,可能是你的兴趣的部分是关于更新,如果它仍然是当前的部分。

  1. 获取对象。
  2. 在本地修改对象。
  3. 发送一条更新请求,指出“如果该对象仍然与旧值相匹配,则将该对象更新为此新值”。

如果操作失败,那么我们可能需要从步骤1

这是当你有一些操作的执行方法再试一次,你想避免持有锁在数据库上。他们还在该文件中声明他们通常如何抵制锁定。

+0

我看到他们如何反对持有锁,但我认为这是为收集而不是单个文件?我希望有一种方法可以执行此操作 2012-07-17 00:03:12

+0

该文档通过基本的'update'查询或更复杂的'find and modify'命令解释了这样做的方法。这个问题是基于你的例子,你首先要对文档数据做一堆本地操作来确定新的修改值。这需要能够将文档从客户端保持在锁定状态。他们不允许这种功能,因为他们表示可能导致潜在的死锁(如果说你的应用程序突然终止)。 – jdi 2012-07-17 00:12:46

+0

MongoDB(特别是PyMongo)是否有一个内置构造来执行此操作@jdi还是必须手动执行此操作?似乎无法找到。 – Ali 2015-10-06 09:59:02

0

您可以在应用程序级别实现文档锁定。

使用场景:

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

我实现DocumentLock类的多线程应用程序并公布它here

悲观锁定更容易比official docs建议乐观锁定使用。在certain conditions下效率更高(在其他情况下效率可能非常低,所以在使用之前必须考虑和评估)。