CouchDB防止冲突上的复制

CouchDB防止冲突上的复制,couchdb,replication,conflict,merge-conflict-resolution,Couchdb,Replication,Conflict,Merge Conflict Resolution,如果存在任何冲突,我希望能够防止从用户的本地实例(其中有许多用户)向中央CouchDB实例进行“推送”(或复制)——本质上是从Git或Mercurial之类的东西复制功能,用户必须在推送到中央服务器之前解决本地副本上的冲突(这样服务器就可以保持“干净”) 就我所见,有两种选择:防止用户在发生冲突时提交(尽管我看不到在不实际完成复制的情况下执行此操作的任何方法),或者完成复制,查看是否存在任何冲突,然后删除推送的复制(以及相关文档)如果存在冲突(尽管如果在重新删除文档之前完成拉取,这也可能导致不良

如果存在任何冲突,我希望能够防止从用户的本地实例(其中有许多用户)向中央CouchDB实例进行“推送”(或复制)——本质上是从Git或Mercurial之类的东西复制功能,用户必须在推送到中央服务器之前解决本地副本上的冲突(这样服务器就可以保持“干净”)

就我所见,有两种选择:防止用户在发生冲突时提交(尽管我看不到在不实际完成复制的情况下执行此操作的任何方法),或者完成复制,查看是否存在任何冲突,然后删除推送的复制(以及相关文档)如果存在冲突(尽管如果在重新删除文档之前完成拉取,这也可能导致不良行为,并且效率有点低)

因此,理想情况下,我希望复制在发生冲突时回滚,并通知我发生了冲突(我不关心冲突的性质,因为这样我就可以启动拉请求复制,在本地数据库上复制中心数据库)


有什么方法可以实现我错过的任何一种方法吗?

您可以尝试使用函数来实现这一点。好的,您可以访问新文档中的_conflicts属性,检查是否存在一些冲突。但我以前从未尝试过

也许像这样的函数会起作用:

function(newDoc, oldDoc, userCtx, secObj) {
  if (newDoc._conflicts && newDoc._conflicts.length) {
    throw({forbidden: 'Your change would cause conflicts. Try resolving the conflicts locally before replicating.'});
  }
}
只需确保此
validate\u doc\u update
功能仅存在于中央数据库上的设计文档中,否则用户将无法将冲突更改“拉”到其本地数据库


请让我知道这是否有效!

虽然这可能不是最好的解决方案,但我做了一些更复杂的事情

  • 向中央数据库发出复制请求,将复制id指定为[RequestingMacAddress].[Guid]
  • 当向中央数据库发出复制推送请求时,我使用自定义视图(使用相同的MAC地址)检查最后一个拉请求ID(在中央数据库上)
  • 我按降序拉取_更改,并确保DB上的最新更改是上面指定的[RequestingMacAddress].[GUID],或者是另一个拉取请求(到另一台机器),并且当前没有任何任务处于活动状态(例如,正在从另一台机器进行推送复制)
  • 如果一切正常-允许推送复制继续,否则将出错

  • 将寻找任何更好的解决方案(如果可用)。

    谢谢Bernhard,我会尝试一下并返回给您。我正在研究的另一个选项是比较该机器最近的拉复制的检查点顺序(使用机器的MAC作为复制id的一部分),然后检查_更改以确定是否有后续更改。但是,如果您的解决方案有效,它会更漂亮!根据我所看到的,我称之为keys(newDoc)并记录了对象属性-很不幸,它似乎只有_id、_rev和_revisions。我猜如果它被删除,那么它可能会删除额外的属性,如文档所示。