如何避免CouchDB中的文档之间的循环依赖

时间:2010-07-07 15:51:10

标签: dependencies couchdb nosql

我很有兴趣在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同时工作:

  1. C1 =得到V

  2. C2 =获得V

  3. C1 =得到A.1,B.1,C1

  4. C2 =得到A.1,B.1,C1

  5. C1 =进行依赖性检查(一切正常)

  6. C2 =进行依赖性检查(一切正常)

  7. C1 =更新V关于预期的B-> C依赖{版本:[[A,1],[B,2],[C,2]]}(一切正常)

  8. C1 =更新B

  9. C2 =尝试更新V关于预期的C->依赖{版本:[[A,2],[B,1],[C,2]]}(此步骤将失败,因为CouchDB乐观锁定)

  10. 一切都很好,直到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中的批量插入/更新语义,它实际上根本不起作用。批量插入/更新不是原子操作。

    有什么解决方法吗?我可以以某种方式绕过它吗?我错过了一些重要的事情吗?

2 个答案:

答案 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美元,那么关系实际上不适用于基于文档的数据库。

考虑根据“参考”重新思考模型,如在引用另一个文档的一个文档中,另一个引用第一个文档。这对于文档来说是完全正常的,但是来自关系世界我们都有思考惯性的问题:)