【问题标题】:Database cluster - asynchronous tasks数据库集群 - 异步任务
【发布时间】:2016-09-27 13:46:47
【问题描述】:

假设我有一个名为“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,因为第一个没有足够的时间来保存他的edit:true。那么如何防止这种行为呢?

第一个解决方案是: 构建一个数组作为数据库请求的提示,并且不允许并行请求,因此所有请求将一个接一个地处理。但在我看来,这是一个糟糕的解决方案,因为系统在某些时候会非常缓慢。

第二种解决方案: 将当前编辑的文档的 documentID 存储在脚本的本地数组中。这会起作用,因为这不是异步过程,第二个用户会立即收到他的错误。

到目前为止一切都很好,但是,如果有一天用户太多并且该系统应该在集群中运行(节点客户端服务器,而不是数据库)怎么办 - 现在第二个解决方案将不再有效,因为每个集群从站会有自己的 documentID 数组。在那里共享会以另一个异步任务结束,并导致上述相同的问题。

现在我没有主意了,大型集群系统通常如何处理这样的问题?

【问题讨论】:

  • 如果同时保存文件,会产生冲突。因此,您的任何解决方案都没有用。使用更新处理程序可减少发生冲突的机会,但仍有可能发生。

标签: javascript asynchronous couchdb


【解决方案1】:

CouchDB 使用MVCC 来维护数据库的一致性。更新文档时,您必须同时提供 ID (_id) 和修订号 (_rev),否则您的更改将被拒绝。

这意味着如果 2 个客户端读取版本 1 的文档,并且都尝试使用相同的版本号写入更改,则只有第一个客户端会被数据库接受。第二个客户端将收到一个错误,它应该获取文档的最新版本才能继续。

在单节点环境中,此模型可彻底防止冲突。但是,在发生复制的情况下,即使使用 MVCC,仍然可能会发生冲突。这是因为从技术上讲,冲突的修订可以在相互复制之前写入不同的节点。在这种情况下,CouchDB 将记录冲突并由您的应用程序负责解决。

CouchDB 拥有一流的文档,尤其是我强烈推荐用于此主题的 an article all about conflicts and replication

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多