我很有兴趣在CouchDB中建立文档之间的关系。假设我有三个文档A,B和C.这些文档可以互相引用,但是存在一个应用约束,即不能发生循环依赖。
让我们举一个例子( - >是依赖的标记):
A - >乙
C
两个客户端(C1,C2)尝试并发修改:
C1 = B - > ç
C2 = C - >甲
如果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 =更新V关于预期的B-> C依赖{版本:[[A,1],[B,2],[C,2]]}(一切正常)
C1 =更新B
C2 =尝试更新V关于预期的C->依赖{版本:[[A,2],[B,1],[C,2]]}(此步骤将失败,因为CouchDB乐观锁定)
一切都很好,直到C1在步骤7和8之间崩溃。现在批量插入/更新即将到场。
7.)C1 =关于预期B-> C依赖的更新V {版本:[[A,1],[B,2],[C,2]]}(一切正常)并更新B
不幸的是,由于CouchDB http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API#Transactional_Semantics_with_Bulk_Updates中的批量插入/更新语义,它实际上根本不起作用。批量插入/更新不是原子操作。
有什么解决方法吗?我可以以某种方式绕过它吗?我错过了一些重要的事情吗?
答案 0 :(得分:0)
两个客户端(C1,C2)尝试并发 修改:
C1 = B - > ç
C2 = C - >甲
如果C1和C2成功,那么就会有 周期。问题是如何预防 它?
这是不可预防的。如果C1正在对服务器X起作用,而C2正在对服务器Y起作用,并且X和Y未在网络上连接,那该怎么办?当重新连接和复制X和Y时,文档B和C最终都将被编辑。
当我们说CouchDB在单个文档上是事务性时,这就是我们的意思。
答案 1 :(得分:0)
如果我可以在这里添加0.02美元,那么关系实际上不适用于基于文档的数据库。
考虑根据“参考”重新思考模型,如在引用另一个文档的一个文档中,另一个引用第一个文档。这对于文档来说是完全正常的,但是来自关系世界我们都有思考惯性的问题:)