MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Lösung für Bulk FindAndModify in MongoDB

Wie Sie bereits erwähnt haben, gibt es derzeit keine saubere Möglichkeit, das zu tun, was Sie wollen. Der derzeit beste Ansatz für Vorgänge wie den, den Sie benötigen, ist dieser :

  1. Leser wählt X Dokumente mit geeignetem Limit und Sortierung aus
  2. Reader markiert die von 1) zurückgegebenen Dokumente mit seiner eigenen eindeutigen Reader-ID (e.g. update({_id:{$in:[<result set ids>]}, state:"available", $isolated:1}, {$set:{readerId:<your reader's ID>, state:"processing"}}, false, true) )
  3. Reader wählt alle als in Bearbeitung markierten Dokumente mit eigener Reader-ID aus. An dieser Stelle ist Ihnen garantiert, dass Sie ausschließlichen Zugriff auf den resultierenden Dokumentensatz haben.
  4. Bieten Sie die Ergebnismenge aus 3) für Ihre Bearbeitung an.

Beachten Sie, dass dies sogar in sehr gleichzeitigen Situationen funktioniert, da ein Leser niemals Dokumente reservieren kann, die nicht bereits von einem anderen Leser reserviert wurden (beachten Sie, dass Schritt 2 nur aktuell verfügbare Dokumente reservieren kann und Schreibvorgänge atomar sind). Ich würde auch einen Zeitstempel mit der Reservierungszeit hinzufügen, wenn Sie in der Lage sein möchten, Reservierungen zeitlich zu überschreiten (z. B. für Szenarien, in denen Lesegeräte abstürzen/fehlschlagen könnten).

BEARBEITEN:Weitere Details :

Alle Schreiboperationen können gelegentlich für anstehende Operationen nachgeben, wenn das Schreiben relativ lange dauert. Das bedeutet, dass in Schritt 2) möglicherweise nicht alle in Schritt 1) ​​markierten Dokumente angezeigt werden, es sei denn, Sie führen die folgenden Schritte aus:

  • Verwenden Sie einen geeigneten "w"-Wert (Write Concern), also 1 oder höher. Dadurch wird sichergestellt, dass die Verbindung, auf der die Schreiboperation aufgerufen wird, darauf wartet, dass sie abgeschlossen wird, unabhängig davon, ob sie nachgibt.
  • Stellen Sie sicher, dass Sie den Lesevorgang in Schritt 2 auf derselben Verbindung (nur relevant für Replikatsätze mit aktivierten SlaveOk-Lesevorgängen) oder Thread durchführen, damit sie garantiert sequentiell sind. Ersteres kann in den meisten Treibern mit den Methoden "requestStart" und "requestDone" oder ähnlichem durchgeführt werden (Java-Dokumentation hier ).
    • Fügen Sie das $isolated-Flag zu Ihren Multi-Updates hinzu, um sicherzustellen, dass es nicht mit anderen Schreibvorgängen verschachtelt werden kann.

Siehe auch Kommentare zur Diskussion bezüglich Atomarität/Isolation. Ich bin fälschlicherweise davon ausgegangen, dass Multi-Updates isoliert wurden. Sie sind es nicht, oder zumindest nicht standardmäßig.