2014-07-17 3 views
3

Je voudrais mettre à jour un document qui implique la lecture d'autres collections et modifications complexes, donc les opérateurs de mise à jour dans findAndModify() ne peuvent pas servir mon but.Gestion des conflits dans trouver, modifier, enregistrer le flux dans MongoDB avec Mongoose

Voici ce que je:

Collection.findById(id, function (err, doc) { 

    // read from other collection, validation 
    // modify fields in doc according to user input 
    // (with decent amount of logic) 

    doc.save(function (err, doc) { 
     if (err) { 
     return res.json(500, { message: err }); 
     } 

     return res.json(200, doc); 
    }); 
} 

Mon inquiétude est que ce flux pourrait provoquer des conflits si plusieurs clients modifie des le même document.
On dit que here:

Opérations sur un document unique sont toujours atomique avec des bases de données MongoDB

Je suis un peu confus au sujet de ce que signifie Operations.

  • Est-ce que cela signifie que le findById() acquerrons le verrou jusqu'à doc est hors de portée (après la réponse est envoyée), donc il n'y aurait pas de conflits? (Je ne pense pas)
  • Si non, comment modifier mon code pour supporter plusieurs clients sachant qu'ils vont modifier Collection?
  • Est-ce que Mongoose signale un conflit s'il survient?
  • Comment gérer le conflit possible? Est-il possible de verrouiller manuellement la collection?
    • Je vois la suggestion d'utiliser versionKey de mangouste (ou horodatage) et une nouvelle tentative pour le document périmé
    • Ne pas utiliser MongoDB tout à fait ...

Merci.


EDIT

Merci @jibsales pour le pointeur, j'utilise maintenant versionKey (horodatage travaillera également) de mangouste pour éviter les conflits livrez.

aaronheckmann — Mongoose v3 part 1 :: Versioning

Voir cet exemple de code:
https://gist.github.com/anonymous/9dc837b1ef2831c97fe8

+0

Avez-vous du code asynchrone dans votre bloc de commentaire (de logique supplémentaire)? Il semble que vous le faites, auquel cas vous pourriez finir par sauvegarder des données obsolètes. Vous pourriez avoir du succès avec quelque chose comme ceci: https://www.npmjs.org/package/mongoose-timestamp. – dylants

+0

Oui, j'ai également trouvé quelques suggestions pour utiliser la version de Mongoose et réessayer pour le document périmé. Est-ce ce que vous suggérez? – leesei

Répondre

3

opérations fait référence à lecture/écriture. Gardez à l'esprit que MongoDB n'est pas une couche de données conforme ACID et si vous avez besoin d'une véritable conformité ACID, il vaut mieux choisir une autre technologie. Cela dit, vous pouvez obtenir l'atomicité et l'isolation via la technique de validation en deux phases outlined in this article in the MongoDB docs. Ce n'est pas une petite entreprise, alors préparez-vous à un gros travail, car vous aurez besoin de travailler avec le pilote natif au lieu de Mongoose. Encore une fois, ma suggestion finale est de ne pas boire le koolaid NoSQL si vous avez besoin d'un support de transaction dont vous avez l'impression.

+0

Je vois une suggestion pour utiliser la version de Mongoose et réessayer après la recherche, recommandez-vous une telle solution? – leesei

1

Lorsque MongoDB reçoit une demande de mise à jour d'un document, il verrouille la base de données jusqu'à la fin de l'opération. Toute autre requête reçue par MongoDB attendra que l'opération de verrouillage soit terminée et que la base de données soit déverrouillée. Ce comportement de verrouillage/attente est automatique, il n'y a donc aucun conflit à gérer.Vous trouverez plus d'informations sur ce comportement dans la section Concurrency de la FAQ.

Voir la réponse de jibsales pour les liens vers la technique recommandée par MongoDB pour effectuer des transactions multi-documents.

Il existe deux bases de données NoSQL qui effectuent des transactions ACID complètes, ce qui vous faciliterait grandement la vie. FoundationDB est une telle base de données. Les données sont stockées en tant que valeur-clé, mais elles prennent en charge plusieurs modèles de données via des couches. Description complète: Je suis ingénieur chez FoundationDB.

Questions connexes