假设我有一个名为"products“的couchDB数据库和一个带有表单的前端。现在,如果用户在表单中打开此数据库中的文档,我希望阻止其他用户编辑此特定文档。
通常很简单:
-> read document from couchDB
-> set a variable to true like: { edit : true }
-> save (merge) document to couchDB
-> if someone else tries to open the document he will receive an error, becaus of edit:true.但是,如果两个用户同时打开文档呢?该函数将被调用两次,当第二个函数打开文档时,他将错误地收到edit:false,因为第一个函数没有足够的时间保存他的编辑:true。那么,如何防止这种行为呢?
第一个解决方案是:构建一个数组作为数据库请求的线索,并且不允许并行请求,因此所有请求都将一个接一个地处理。但在我看来,这是一个糟糕的解决方案,因为系统在某些时候会变得令人难以置信地慢。
第二种解决方案:将当前编辑的文档的documentID存储在脚本的本地数组中。这是可行的,因为这不是异步流程,第二个用户会立即收到他的错误。
到目前为止还不错,但是,如果有一天用户太多,并且这个系统应该在集群(节点客户端服务器,而不是数据库)中运行,那么现在第二种解决方案将不再有效,因为每个集群从站都将拥有自己的documentID数组。在那里共享将以另一个异步任务结束,并导致上述相同的问题。
现在我没有想法了,大型集群系统通常是如何处理这样的问题的?
发布于 2016-09-26 14:56:29
CouchDB使用MVCC来维护数据库中的一致性。更新文档时,必须同时提供ID (_id)和修订号(_rev),否则更改将被拒绝。
这意味着,如果两个客户端读取修订版1的文档,并且两个客户端都尝试使用相同的修订号写入更改,则只有第一个客户端将被数据库接受。第二个客户端将收到一个错误,它应该获取文档的最新版本才能继续。
在单节点环境中,此模型可完全防止冲突。但是,在发生复制的情况下,即使使用MVCC,也仍然有可能发生冲突。这是因为从技术上讲,冲突的修订版本可以在彼此复制之前写入不同的节点。在这种情况下,CouchDB将记录冲突,您的应用程序负责解决它们。
CouchDB有一流的文档,特别是他们的an article all about conflicts and replication,我强烈推荐这个主题。
https://stackoverflow.com/questions/39693692
复制相似问题