sql >> Base de Datos >  >> NoSQL >> MongoDB

Solución a Bulk FindAndModify en MongoDB

Como mencionas, actualmente no hay una forma limpia de hacer lo que quieres. El mejor enfoque en este momento para operaciones como la que necesita es este:

  1. El lector selecciona X documentos con el límite y la clasificación adecuados
  2. Reader marca los documentos devueltos por 1) con su propia ID de lector única (e.g. update({_id:{$in:[<result set ids>]}, state:"available", $isolated:1}, {$set:{readerId:<your reader's ID>, state:"processing"}}, false, true) )
  3. Reader selecciona todos los documentos marcados como procesamiento y con su propia ID de lector. En este punto, se garantiza que tiene acceso exclusivo al conjunto de documentos resultante.
  4. Ofrezca el conjunto de resultados de 3) para su procesamiento.

Tenga en cuenta que esto incluso funciona en situaciones muy concurrentes, ya que un lector nunca puede reservar documentos que no hayan sido reservados por otro lector (tenga en cuenta que el paso 2 solo puede reservar documentos actualmente disponibles y las escrituras son atómicas). También agregaría una marca de tiempo con el tiempo de reserva si desea poder agotar el tiempo de espera de las reservas (por ejemplo, para escenarios en los que los lectores pueden bloquearse o fallar).

EDITAR:Más detalles:

Todas las operaciones de escritura pueden dar lugar ocasionalmente a operaciones pendientes si la escritura lleva un tiempo relativamente largo. Esto significa que el paso 2) podría no ver todos los documentos marcados por el paso 1) a menos que siga los siguientes pasos:

  • Utilice un valor "w" (escriba preocupación), que signifique 1 o más. Esto garantizará que la conexión en la que se invoca la operación de escritura esperará a que se complete, independientemente de que rinda.
  • Asegúrese de realizar la lectura en el paso 2 en la misma conexión (solo relevante para conjuntos de réplicas con lecturas SlaveOk habilitadas) o subproceso para garantizar que sean secuenciales. Lo primero se puede hacer en la mayoría de los controladores con los métodos "requestStart" y "requestDone" o similares (documentación de Java aquí ).
    • Agregue el indicador $aislado a sus actualizaciones múltiples para asegurarse de que no se pueda intercalar con otras operaciones de escritura.

También vea los comentarios para la discusión sobre atomicidad/aislamiento. Asumí incorrectamente que las actualizaciones múltiples estaban aisladas. No lo son, o al menos no por defecto.