MongoDB Go (golang) mit mgo: Wie kann ich einen Datensatz aktualisieren, finden Sie heraus, ob der update erfolgreich war und die Daten in einer einzigen atomaren operation?
Ich bin mit mgo-Treiber für MongoDB unter Gehen.
Meine Anwendung fragt für eine Aufgabe (mit nur einem Datensatz, wählen Sie im Mongo aus einer Sammlung, genannt "jobs") und dann registriert sich selbst als ein asignee um dieser Aufgabe (ein update für die gleiche "Arbeit" aufnehmen, die Einstellung sich selbst als Rechtsnachfolger).
Das Programm läuft auf mehreren Rechnern, alle sprechen die gleiche Mongo. Wenn mein Programm listet die verfügbaren Aufgaben und nimmt dann eine, andere Instanzen möglicherweise bereits erhalten haben, die Zuordnung, und die aktuelle Belegung wäre gescheitert.
Wie kann ich sicherstellen, dass die Platte, die ich Lesen und aktualisieren Sie dann tut oder nicht über einen bestimmten Wert (in diesem Fall ein Zessionar), in der Zeit werden aktualisiert?
Ich versuche zu bekommen eine Arbeit, egal was, so dass ich denke, ich sollte zuerst wählen Sie eine ausstehende Aufgabe und versuchen, Sie zu ordnen, ihn zu halten, nur in dem Fall, dass die Aktualisierung erfolgreich war.
Also, meine Abfrage sollte so etwas wie:
"Aus allen Aufzeichnungen der Sammlung 'jobs', update nur eine, asignee=null, Einstellung für meine ID als Rechtsnachfolger. Dann, gib mir den Datensatz also ich könnte den job."
Wie konnte ich nur Ausdrücken, dass mit mgo-Treiber für die Go?
InformationsquelleAutor Sebastián Grignoli | 2012-07-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich hoffe, Sie haben die Kommentare auf die Antwort, die Sie gewählt haben, sondern, dass der Ansatz falsch ist. Tun, eine select und dann update führt in einer Rundreise und zwei Maschinen und Holen für den gleichen job, bevor einer von Ihnen aktualisiert werden kann
assignee
. Sie müssen verwenden Sie diefindAndModify
Methode statt: http://www.mongodb.org/display/DOCS/findAndModify+KommandoWarum brauchen Sie, um wählen Sie ALLE Optionen? Haben Sie sagen, Sie brauchen nur zu wählen, ist noch nicht getroffen (aka Zessionar == null)?
Du hast Recht. Meine Bedürfnisse stellte sich heraus, anders zu sein als das, was ich dachte, als ich schrieb, die Frage, aber deine Antwort passt die Frage besser.
Die findAndModify Befehl ist bequem, unterstützt von mgo über die Abfrage.Apply - Methode. Bitte siehe die Antwort weiter unten für details.
InformationsquelleAutor Steven Luu
Dies ist eine alte Frage, aber nur für den Fall dass jemand noch beobachten, zu Hause, das ist schön unterstützt über die Abfrage.Bewerben Methode. Laufen tut er die
findAndModify
Befehl wie in einer anderen Antwort, aber es ist günstig, versteckt hinter Gehen Güte.Dem Beispiel in der Dokumentation entspricht ziemlich genau der Frage hier:
InformationsquelleAutor Gustavo Niemeyer
Die MongoDB Jungs beschreiben ein ähnliches Szenario in der offiziellen Dokumentation: http://www.mongodb.org/display/DOCS/Atomic+Operationen
Im Grunde alles, was Sie tun müssen, ist zu Holen, jeden job mit
assignee=null
. Nehmen wir an, Sie bekommen den job mit der_id=42
zurück. Sie können dann gehen Sie vor und ändern Sie das Dokument lokal, indemassignee="worker1.example.com"
- und call - Sammlung.Update() mit dem Selektor{_id=42, assignee=null}
und Ihre aktualisierte Dokument. Wenn die Datenbank noch in der Lage ist, ein Dokument zu finden, das entspricht dieser Selektor, es wird an die Stelle des Dokuments atomar. Ansonsten bekommen Sie ErrNotFound, was darauf hinweist, dass ein anderer thread bereits behauptet, die Aufgabe. Wenn das der Fall ist, versuchen Sie es erneut.Der select+update muss nicht atomar sind für diesen bestimmten Algorithmus. Solange das update selbst ist atomar (das ist im Grunde ein CompareAndSwap / CompareExchange-operation) ist alles in Ordnung.
Wenn zwei Maschinen wählen Sie die gleiche Aufgabe auf die erste Abfrage, die man von Ihnen nicht auf das update. Sicher, das Endergebnis kann immer sein, dass die Daten in der Datenbank wird nie unvereinbar, aber das scheitern der Fall mit zwei getrennten Operationen verursacht eine Menge unnötige hin und her. Dies ist... der ganze Grund der findAndModify Befehl existiert.
InformationsquelleAutor tux21b