2012-05-09 4 views
4

Schéma:MongoDB mise à jour plusieurs documents

{ 
    name: String, 
    available: Boolean, 
    for: String 
} 

il y a "un":

{ 
    name: "a", 
    available: true, 
    for: ["b", "c"] 
} 

et "b":

{ 
    name: "b", 
    available: true, 
    for: ["a", "b] 
} 

si je mets à jour a.available = false, Je devrais mettre à jour b.available = false en même temps. comment pourrais-je mettre à jour deux documents et m'assurer qu'il n'y aurait pas d'autre processus/thread obtenant "b" entre le moment de mettre à jour "a" et "b".

Répondre

5

MongoDB ne prend pas en charge les transactions atomiques. Donc, si vous devez faire la première mise à jour "se défaire" si la deuxième mise à jour échoue, alors vous n'avez pas de chance. Toutefois, dans certains cas limités, MongoDB prend en charge les mises à jour isolées. La mise à jour n'est pas tout ou rien, mais MongoDB garantira que personne d'autre n'écrit dans la collection au milieu de votre écriture.

Quelques importantes mises en garde:

  • Les documents doivent tous être dans la même collection
  • Les mises à jour doivent tous être spécifiés dans une requête

Sur la base de l'exemple que vous avez fourni, votre cas pourrait être admissible.

Here est la documentation décrivant une mise à jour isolée.

Fondamentalement, vous aurez envie de publier la mise à jour semblable à ce qui suit pour mettre atomiquement « disponible » false lorsque le nom est soit « a » ou « b »:

db.blah.update({"name": {"$in": ["a", "b"]}, "$atomic": 1}, {"available": false}); 
+0

mise à jour compte = 1 si nom == "a"; mise à jour compte = 2 si nom == "b". – Kevin

+0

Ce n'est probablement pas possible. Comme je l'ai dit, il y a des limites importantes à cette fonctionnalité - MongoDB n'est pas vraiment conçu pour ce genre de choses. –

3

Si vous avez vraiment besoin , il peut être possible d'implémenter cette logique sur mongodb (dans votre application ou mieux dans un wrapper pour le pilote mongo).

Vous demandez la propriété d'isolation. Une façon d'y parvenir est d'utiliser le modèle MVCC. C'est vraiment exagéré mais c'est pour vous donner une idée de ce que vous pourriez faire si vous avez vraiment besoin à la fois de mongodb et de certaines propriétés ACID.

Une implémentation générique du modèle MVCC est décrite here. Il y a aussi un project sur github pour implémenter ceci, mais c'est un projet java. Vous pouvez également voir ce SO question et leurs réponses. Ma réponse actuelle est juste un résumé de celui-ci. Comment puis-je mettre à jour différents documents de manière atomique avec des valeurs différentes?

Questions connexes