2012-04-06 8 views
7

MongoDB tiene soporte para actualizaciones atómicas. Es decir. Puedo estar seguro de que cuando se actualice un documento, ninguna otra actualización sobrescribirá mi cambio anterior. Mi pregunta se relaciona con la combinación de consulta y declaración de actualización, y se ilustra mejor con el ejemplo que se muestra a continuación.¿Se aplica la atomicidad de actualización de MongoDB tanto a la consulta como a la modificación?

db.foo.update(
{ state : 1, players: { $size: 2 } } , 
{ $push: { players : { new player document } } }, 
false , true); 

En el ejemplo anterior, sólo quieren impulsar un nuevo jugador en una colección de jugadores, si el número de jugadores es igual a 2. Dada la consulta anterior y la instrucción de actualización, es posible que dos cambios simultáneos tanto empujar a un jugador en el mismo documento, porque en el momento de leer el documento, ¿el tamaño de los jugadores $ es 2? Es decir. ¿la atomicidad se extiende a través de la consulta y actualiza parte de la declaración de actualización o no?

Editar Más secuencia en profundidad de los eventos:

Considere disparar la misma actualización dos veces (U1 y U2) al mismo tiempo. ¿Es posible la siguiente secuencia de eventos o no?

  1. U1 encuentra que el documento # 1 coincide con la parte de consulta de la declaración de actualización .
  2. U2 encuentra que el documento # 1 coincide con la parte de consulta de la declaración de actualización.
  3. U1 empuja un nuevo jugador en el documento n. ° 1.
  4. U2 empuja a un nuevo jugador en el documento n. ° 1.

El resultado final es que el documento # 1 contiene un jugador más de lo esperado, porque tanto U1 como U2 tenían la impresión de que el documento # 1 contiene solo dos jugadores.

Respuesta

0

Actualización: no estoy seguro de mi conocimiento ... Ver "The ABA Nuance". No acepte esta respuesta (o mi comentario a continuación), ya que probablemente no sea correcta. Me encantaría ser corregido.


Su explicación de atómico es incorrecta (puedo estar seguro de que cuando se actualiza un documento de ninguna otra actualización se sobreponen a mi cambio anterior). Otras actualizaciones pueden (y lo harán) sobrescribir su cambio. Pero no lo harán de una manera que pueda interferir con la integridad de su consulta.

Es importante saber que las actualizaciones de MongoDB son atomic on single document. Entonces, cuando un documento coincide con su consulta, está "bloqueado" y listo para una actualización. Tenga en cuenta que su actualización ($push) funciona dentro del mismo documento que estaba bloqueado. Cuando la actualización finaliza, se libera el bloqueo.

No estoy seguro de entender "hace el lapso atomicidad a través de la parte de consulta y actualización de la instrucción de actualización o no", sino: medios atómicos que otros consultas no puede meterse con nuestra consulta. Nuestra consulta puede cambiar datos que están "bloqueados" por sí mismos.

Descargo de responsabilidad: no estoy al tanto de los mecanismos internos que utiliza MongoDB para garantizar esta atomicidad, por lo que esta descripción puede faltar desde el punto de vista técnico (especialmente en relación con el bloqueo), pero es válida conceptualmente. Así es como funciona desde el punto de vista externo.

+0

Gracias por su respuesta. He actualizado mi pregunta con una secuencia de eventos, que espero aclare un poco. Ahora me doy cuenta de que lo que estoy preguntando no es atomicidad, sino una transacción (bloqueo) a nivel de documento. –

+0

Sí, eso aclara la pregunta. No tienes nada de qué preocuparte. Nada puede alterar el documento entre búsqueda y actualización (pasos 2 y 4) o la operación no sería atómica. Si no funciona de esta manera, entonces es un error y se debe informar como tal. – johndodo

0

Con la secuencia de eventos que anota, puede tener demasiados jugadores.El "buscar" y la "actualización" de la actualización se parecen mucho a hacerlo usted mismo con un "hallazgo" y luego una "actualización" en cada uno de los documentos que está iterando. Probablemente quiera echar un vistazo al operador "$ atomic": http://www.mongodb.org/display/DOCS/Atomic+Operations#AtomicOperations-ApplyingtoMultipleObjectsAtOnce

+1

Tenga en cuenta que OP está emitiendo solo 2 actualizaciones (U1 y U2), los pasos están ahí para ilustrar un posible conflicto. – johndodo

Cuestiones relacionadas