问题
I'm using pymongo in a web app, and want to do something of the form:
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)
Is there any simple way way I can handle multiple requests dealing with the same document and prevent one from clobbering the results of another / be made invalid because it's editing a stale version?
回答1:
Take a look at the section in the mongodb docs on Atomic Operations
The section that might be of interest to you is the part about updating if it is still current.
- Fetch the object.
- Modify the object locally.
- Send an update request that says "update the object to this new value if it still matches its old value".
Should the operation fail, we might then want to try again from step 1.
This is the approach for when you have a number of operations to perform and you want to avoid holding a lock on the database. They also state in that doc how they are generally against holding a lock.
回答2:
You can implement document locks at application level.
Usage scenario:
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)
I've implemented DocumentLock class for multi-threaded application and published it here.
This pessimistic locking is much easier to use than optimistic locking advised in official docs. It is also more efficient under certain conditions (and might be very inefficient under others, so you have to think and evaluate before using it).
来源:https://stackoverflow.com/questions/11496763/locking-a-document-in-mongodb