【发布时间】:2011-03-12 21:48:47
【问题描述】:
我对 CouchDB 中文档之间的关系建模很感兴趣。假设我有三个文档 A、B 和 C。这些文档可以相互引用,但是有一个应用程序约束,不能发生循环依赖。
举个例子(-> 是依赖的标记):
A -> B
C
两个客户端(C1、C2)尝试并发修改:
C1 = B -> C
C2 = C -> A
如果 C1 和 C2 成功,就会有循环。问题是如何预防?
我正在考虑它,似乎我需要一种用于文档和原子批量更新的粗粒度锁。问题是原子批量更新。 CouchDB 支持批量更新,但在版本冲突的情况下不回滚。什么意思:
假设我们有文档 V。该文档代表全局版本(粗粒度锁定)并保存给定文档修订版本的相关文档(A、B、C)的版本。
V {
_rev: 1,
versions: [[A,1],[B,1],[C,1]]
}
C1 和 C2 同时工作:
C1 = 得到 V
C2 = 得到 V
C1 = 获取 A.1、B.1、C1
C2 = 获取 A.1、B.1、C1
C1 = 进行依赖性检查(一切正常)
C2 = 进行依赖性检查(一切正常)
-
C1 = 根据预期的 B->C 依赖关系更新 V {版本:[[A,1],[B,2],[C,2]] }(一切正常)
C1 = 更新 B
C2 = 尝试更新 V 关于预期的 C->A 依赖 {版本:[[A,2],[B,1],[C,2]] }(此步骤将失败,因为CouchDB 乐观锁)
一切都很好,直到 C1 在第 7 步和第 8 步之间崩溃。现在批量插入/更新即将到来。
7.) C1 = 更新 V 关于预期的 B->C 依赖 {versions: [[A,1],[B,2],[C,2]] }(一切正常)并更新 B
多么好的解决方案,不幸的是它根本不起作用,因为 CouchDB http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API#Transactional_Semantics_with_Bulk_Updates 中的批量插入/更新语义。批量插入/更新不是原子操作。
有什么解决方法吗?我可以以某种方式绕过它吗?我错过了什么重要的事情吗?
【问题讨论】:
标签: dependencies couchdb nosql