No MongoDB, as operações de gravação são atômicas no nível de documento único, mesmo que modifiquem vários valores. Para atualizações paralelas, cada comando garante que a condição da query ainda corresponda.
Para evitar conflitos durante as atualizações simultâneas, inclua o valor atual esperado no filtro de atualização.
Casos de uso
Os exemplos nesta página usam dados do conjunto de dados de amostrasample_mflix . Para obter detalhes sobre como carregar esse conjunto de dados em sua implantação autogerenciada do MongoDB, consulte Carregar o conjunto de dados de amostra. Se você fez modificações nos bancos de dados de amostra, talvez seja necessário descartar e recriar os bancos de dados para executar os exemplos nesta página.
Considere uma collection com este documento:
db.movies.insertOne( { _id: 1, num_mflix_comments: 80 } )
Essas operações de atualização ocorrem simultaneamente:
( // Update A db.movies.updateOne( { _id: 1, num_mflix_comments: 80 }, { $set: { num_mflix_comments: 90 } } ), // Update B db.movies.updateOne( { _id: 1, num_mflix_comments: 80 }, { $set: { num_mflix_comments: 100 } } ) )
Uma atualização define num_mflix_comments como 90 ou 100. A segunda atualização então não corresponde a { num_mflix_comments: 80 } e não é executada.
Aviso
Filtrar em um campo que você não atualiza pode causar resultados inesperados durante as atualizações simultâneas. Considere estas operações:
( // Update A db.movies.updateOne( { _id: 1 }, { $set: { num_mflix_comments: 90 } } ), // Update B db.movies.updateOne( { _id: 1 }, { $set: { num_mflix_comments: 100 } } ) )
Ambas as atualizações correspondem a { _id: 1 }, portanto, ambas são executadas. A segunda atualização substitui a primeira. O primeiro cliente não recebe aviso de que sua atualização foi perdida.
Para evitar conflitos ao filtrar em campos não atualizados, utilize $inc.
Por exemplo, considere as seguintes operações de atualização simultâneas:
( // Update A db.movies.updateOne( { _id: 1 }, { $inc: { num_mflix_comments: 10 } } ), // Update B db.movies.updateOne( { _id: 1 }, { $inc: { num_mflix_comments: 20 } } ) )
Ambas as atualizações correspondem a { _id: 1 }. Como eles incrementam em vez de definir o valor, eles não se substituem. O num_mflix_comments final é 110.
Dica
Store Unique Values
Para impor exclusividade, crie um índice único. Isso evita dados duplicados em inserções e atualizações. Você também pode criar índices únicos em múltiplos campos. Consulte Criar um índice único de campo único.
Detalhes
Esta seção descreve detalhes adicionais para transações multidocumento.
Quando uma única operação de gravação (por exemplo, db.collection.updateMany()) modifica vários documentos, a modificação de cada documento é atômica, mas a operação como um todo não é atômica.
Ao realizar operações de escrita de vários documentos, seja por meio de uma única operação de escrita ou de várias operações de escrita, outras operações podem ser intercaladas.
Para situações que exigem atomicidade de leituras e escritos em vários documentos (em uma única coleção ou várias coleções), o MongoDB suporta transações distribuídas, incluindo transações em conjuntos de réplicas e clusters fragmentados.
Para obter mais informações, consulte transações.
Importante
Na maioria dos casos, uma transação distribuída incorre em um custo de desempenho maior do que as gravações de um único documento, e a disponibilidade de transações distribuídas não deve substituir o design eficaz do esquema. Em muitos cenários, o modelo de dados desnormalizado (documentos e arrays incorporados) continuará a ser ideal para seus dados e casos de uso. Ou seja, para muitos cenários, modelar seus dados adequadamente minimizará a necessidade de transações distribuídas.
Para considerações adicionais sobre o uso de transações (como limite de tempo de execução e limite de tamanho do oplog), consulte também Considerações de produção.