En MongoDB, las operaciones de guardar son atómica al nivel de un solo documento, incluso si se modifican múltiples valores. Para actualizaciones paralelas, cada comando garantiza que la condición de la query siga coincidiendo.
Para evitar conflictos durante actualizaciones simultáneas, incluye el valor actual esperado en el filtro de actualización.
Casos de uso
Considere una colección con este documento:
db.games.insertOne( { _id: 1, score: 80 } )
Estas operaciones de actualización ocurren simultáneamente:
// Update A db.games.updateOne( { score: 80 }, { $set: { score: 90 } } ) // Update B db.games.updateOne( { score: 80 }, { $set: { score: 100 } } )
Un conjunto de actualización score a 90 o 100. La segunda actualización luego falla en coincidir con { score: 80 } y no se ejecuta.
Advertencia
Filtrar un campo que no actualizas puede provocar resultados inesperados durante actualizaciones concurrentes. Considere estas operaciones:
// Update A db.games.updateOne( { _id: 1 }, { $set: { score: 90 } } ) // Update B db.games.updateOne( { _id: 1 }, { $set: { score: 100 } } )
Ambas actualizaciones coinciden con { _id: 1 }, por lo que ambas se ejecutan. La segunda actualización sobrescribe la primera. El primer cliente no recibe ninguna advertencia de que su actualización se haya perdido.
Para evitar conflictos al filtrar campos no actualizados, utiliza $inc.
Por ejemplo, considere las siguientes operaciones de actualización simultáneas:
// Update A db.games.updateOne( { _id: 1 }, { $inc: { score: 10 } } ) // Update B db.games.updateOne( { _id: 1 }, { $inc: { score: 20 } } )
Ambas actualizaciones coinciden con { _id: 1 }. Debido a que incrementan en vez de establecer el valor, no se sobreescriben entre sí. El score final es 110.
Tip
Store Unique Values
Para garantizar la unicidad, cree un índice único. Esto evita la duplicación de datos en inserciones y actualizaciones. También puede crear índices únicos en varios campos. Consulte Crear un índice único de un solo campo.
Detalles
Esta sección describe detalles adicionales para transacción multi-documento.
Cuando una sola operación de guardado (p. ej. db.collection.updateMany()) modifica múltiples documentos; la modificación de cada documento es atómica, pero la operación en su conjunto no es atómica.
Al realizar Operaciones de guardado multidocumento, ya sea a través de una sola Operación de guardado o de múltiples Operaciones de guardado, otras Operaciones pueden intercalarse.
Para situaciones que requieren atomicidad de las lecturas y escrituras en varios documentos (en una sola colección o en varias), MongoDB admite transacciones distribuidas, incluidas las transacciones en sets de réplica y clústeres fragmentados.
Para obtener más información, consulte Transacciones.
Importante
En la mayoría de los casos, una transacción distribuida incurre en un costo de rendimiento mayor que las escrituras de documentos individuales, y la disponibilidad de transacciones distribuidas no debería ser un sustituto para un diseño de esquema efectivo. Para muchos casos, el modelo de datos desnormalizado (documento incrustado y matrices) seguirá siendo óptimo para tus datos y casos de uso. Es decir, en muchos casos, modelar tus datos de forma adecuada minimizará la necesidad de transacciones distribuidas.
Para consideraciones adicionales sobre el uso de transacciones (como el límite de tiempo de ejecución y el límite de tamaño del oplog), consulta también las consideraciones de producción.