2010-07-07 14 views
1

Je suis intéressant dans la modélisation des relations entre les documents dans CouchDB. Disons que j'ai trois documents A, B et C. Ces documents peuvent se référer les uns aux autres, mais il y a une contrainte d'application que la dépendance cyclique ne doit pas se produire.Comment éviter les dépendances cycliques entre les documents dans CouchDB

permet de prendre un exemple (-> est un marqueur de dépendance):

A -> B

C

deux clients (C1, C2) essayer modification simultanée:

C1 = B -> C

C2 = C -> A

Si C1 et C2 sont réussis, il y aura un cycle. La question est de savoir comment l'éviter? Je pensais à ce sujet et il me semble que j'ai besoin d'une sorte de verrou à grain grossier pour les documents et la mise à jour atomique en vrac. Le problème est la mise à jour en masse atomique. CouchDB prend en charge la mise à jour en bloc, mais sans restauration en cas de conflit de version. Ce que cela signifie:

Supposons que nous ayons le document V. Ce document représente la version globale (verrou grossier) et contient la version des documents connexes (A, B, C) pour une révision de document donnée.

V { 
    _rev: 1, 
    versions: [[A,1],[B,1],[C,1]] 
} 

C1 et C2 travail en même temps:

  1. C1 = get V

  2. C2 = get V

  3. C1 = obtenir A.1, B.1, C1

  4. C2 = obtenir A.1, B.1, C1

  5. C1 = faire la vérification des dépendances (tout est OK)

  6. C2 = faire la vérification des dépendances (tout est OK)

  7. C1 = mise à jour V en ce qui concerne à destinés B-> dépendance C {versions: [ [A, 1], [B 2], [C, 2]]} (tout est OK)

  8. C1 = mise à jour B

  9. C2 = essayant en ce qui concerne la mise à jour V à l'intention C-> A dépendance {versions: [[A, 2], [B, 1], [C, 2]]} (cette étape échouera, à cause de CouchDB verrouillage optimiste)

Tout va bien et bien jusqu'à ce que C1 se bloque entre l'étape 7. et 8. Maintenant l'insertion/mise à jour en vrac arrivant à la scène.

7.) C1 = mise à jour V en ce qui concerne à B- destiné> dépendance de C {versions: [[A, 1], [B 2], [C, 2]]} (tout est OK) et mise à jour B

Quelle belle solution, malheureusement cela ne marche pas du tout, à cause de la sémantique d'insertion/mise à jour en vrac dans CouchDB http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API#Transactional_Semantics_with_Bulk_Updates. L'insertion/mise à jour en masse n'est pas une opération atomique.

Y at-il une solution de contournement pour cela? Puis-je le contourner d'une manière ou d'une autre? Ai-je manqué quelque chose d'important?

Répondre

0

Deux clients (C1, C2) essayer concurrente modification :

C1 = B -> C

C2 = C -> A

Si C1 et C2 sont réussissent il y aura être cycle. La question est de savoir comment prévenir ?

Ceci n'est pas évitable. Que se passe-t-il si C1 travaille contre le serveur X et que C2 travaille avec le serveur Y? X et Y ne sont pas connectés au réseau. Lorsque X et Y sont reconnectés et répliqués, les deux documents B et C finiront par être édités.

C'est ce que nous voulons dire lorsque nous disons que CouchDB est transactionnel sur un seul document.

0

Si je peux ajouter 0,02 $ ici, les relations ne sont vraiment pas pour le monde des bases de données documentaires. Envisager de repenser le modèle en termes de "référence", comme dans un document référençant l'autre, et l'autre référençant le premier. Ceci est parfaitement normal pour les documents, mais venant du monde relationnel, nous avons tous des problèmes avec l'inertie de la pensée :)