问题
As a newbie to CouchDB or NoSQL in general I can't find a good way of updating two documents, with guarantee that either both are updated or none of them.
In my use case there is a boolean flag in each document. To illustrate, lets assume I'm talking about document of type="citizen" with a boolean attribute isKing. I want to ensure there is exactly one king at a time. It gets tricky when I want to change the king. This requires modification of two documents (to set isKing=true for the new king and isKing=false to the old one).
How do I ensure I won't end up with two or zero kings after some unfortunate concurrent updates?
I was thinking about bulk update, but it doesn't help since it does not support transactions.
Edit: I've seen question Can I do transactions and locks in CouchDB?, but it does not address my case. It also relates to transactions in CouchDB, but that's where similarities end. The problem there is to transactionally read & update one document, while I'm asking about transactional update of two documents. I don't find answers to the other question helpful for my case, but if you think it is duplicate please explain why.
回答1:
Transactional Semantics with Bulk Updates
In short, there are none (by design). However, you can ask CouchDB to check that all the documents in your _bulk_docs request pass all your validation functions. If even one fails, none of the documents are written. You can select this mode by including "all_or_nothing":true in your request.
Handle the revision validation in an own validate_doc_update
function by comparing oldDoc._rev
and newDoc._rev
.
If you let fail the validation of one doc - the other will also not be written.
Attention!!! The answer is valid for CouchDB v1 only. CouchDB v2 is ignoring the "all_or_nothing" property.
来源:https://stackoverflow.com/questions/29491618/transaction-like-update-of-two-documents-using-couchdb