Question

J'imagine foo fait une mise à jour sur le troisième commentaire, comments.2.value, tandis que bar est $pull-ing, en supprimant le premier commentaire.

Si foo se termine d'abord, puis le troisième commentaire est mis à jour avec succès, car l'index est toujours correct.

Mais si bar se termine d'abord, puis l'indice a changé, et foo's comments.2.value n'affecterait plus le troisième commentaire.

Ce scénario est-il possible, et si c'est le cas, je me demande s'il existe des solutions communes pour les mises à jour des éléments de tableau et la condition de course?

Merci !

Était-ce utile?

La solution

La situation que vous avez décrite est théoriquement possible si plusieurs applications accèdent simultanément à la base de données. Pour cette raison, il est préférable, si possible, de donner à chaque membre du tableau un identifiant unique, plutôt que d'accès à des éléments dans le tableau par position.

Par exemple,

> db.myComments.save({_id:1,
comments:[
{cid:1, author:"Marc", comment:"Marc's Comment"}, 
{cid:2, author:"Mike", comment:"Mike's Comment"}, 
{cid:3, author:"Barrie", comment:"Barrie's Comment"}
]})

Si nous voulons modifier le commentaire de Mike, mais que nous ne savons pas nécessairement qu'il apparaîtra deuxième dans le tableau, nous pouvons le mettre à jour comme tel:

> db.myComments.update({_id:1, "comments.cid":2}, {$set:{"comments.$.comment":"Mike's NEW Comment"}})
> db.myComments.find().pretty()
{
    "_id" : 1,
    "comments" : [
        {
            "cid" : 1,
            "author" : "Marc",
            "comment" : "Marc's Comment"
        },
        {
            "author" : "Mike",
            "cid" : 2,
            "comment" : "Mike's NEW Comment"
        },
        {
            "cid" : 3,
            "author" : "Barrie",
            "comment" : "Barrie's Comment"
        }
    ]
}

Nous pourrions même changer tout le sous-document, comme ainsi:

> db.myComments.update({_id:1, "comments.cid":2}, {$set:{"comments.$":{cid:4, author:"someone else", comment:"A completely new comment!"}}})
> db.myComments.find().pretty()
{
    "_id" : 1,
    "comments" : [
        {
            "cid" : 1,
            "author" : "Marc",
            "comment" : "Marc's Comment"
        },
        {
            "cid" : 4,
            "author" : "someone else",
            "comment" : "A completely new comment!"
        },
        {
            "cid" : 3,
            "author" : "Barrie",
            "comment" : "Barrie's Comment"
        }
    ]
}

Le document de requête trouvera la première valeur du tableau qui correspond, et le "$" dans le document de mise à jour fait référence à cette position.

Plus d'informations sur l'opérateur "$" peuvent être trouvées dans la section "l'opérateur de position $" de la documentation "Mise à jour".http://www.mongodb.org/display/docs/updating#updating- the%24pospositionaloperator

J'espère que cela vous donnera une idée de la façon dont votre application peut modifier les valeurs dans un tableau sans faire référence à sa position. Bonne chance!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top