Ich versuche, eine effiziente Methode zu finden, mit der eine Gruppe von Personen eine Reihe von Dateneingabeaufgaben bearbeiten kann. Zuvor hatten wir nur eine Person, die das getan hat, also war das kein Problem. Das Backend ist ein RDBMS und das Frontend ist eine Webanwendung.Zuweisen von Dateneingabeaufgaben an mehrere gleichzeitige Web-App-Benutzer
Derzeit tun wir etwas wie folgt aus:
Um einen Datensatz zur Bearbeitung zuweisen:
SELECT * FROM records WHERE in_edit_queue LIMIT 1;
Dann
Um Änderungen an einer zuvor zugewiesenen Datensatz zu speichern:
UPDATE records SET ..., in_edit_queue = false
WHERE id = ? AND in_edit_queue = true;
Dies bedeutet, dass es möglich ist, dass zwei Benutzer denselben Datensatz für edi erhalten t, und wir bevorzugen die erste, die geltend macht, leise auf Nachreichungen versagt, zB:
- Ein Benutzer lädt bis Datensatz 321 für die Bearbeitung
- Benutzer B Lasten bis Datensatz 321 für die Bearbeitung
- vorträgt Benutzer B Änderungen (sie werden in der DB gespeichert)
- Benutzer A trägt Änderungen (sie in der DB nicht gespeichert werden)
(Anmerkung: Wir können alle unsere Nutzer vertrauen auf akzeptable Daten einreichen, so gibt es keine Notwendigkeit, für uns, um die Daten von th zu halten Die zweite .
Das Problem mit dieser Methode ist, wenn Benutzer zur gleichen Zeit starten und mit etwa der gleichen Geschwindigkeit bearbeiten, sie aktualisieren oft die gleichen Datensätze, aber nur 1 von ihnen wird gespeichert. Mit anderen Worten, eine Menge Mannstunden zu verschwenden. Ich kann das etwas lindern, indem ich zufällige Reihen auswähle, aber ich würde etwas lieber etwas mehr bevorzugen.
Also hier ist, was ich denke ...
eine Tabelle genannt: locked_records (record_id integer, locked_until timestamp)
-- Assign a record for editing:
-- Same as before but also make sure the
-- record is not listed in locked_records...
SELECT * FROM records
WHERE in_edit_queue AND id NOT IN (
SELECT record_id FROM locked_records
WHERE locked_until > now())
LIMIT 1;
-- ..and effectively remove it from
-- the queue for the next 5 minutes
INSERT INTO locked_records (record_id, locked_until)
VALUES (?, now() + 300);
Dann:
UPDATE records SET ..., in_edit_queue = false
WHERE id = ? AND in_edit_queue = true;
DELETE FROM locked_records WHERE record_id = ?;
Ein typischer bearbeiten dauert etwa 30 Sekunden bis 1 Minute , 5 Minuten aus der Warteschlange sollte eine gute Menge sein. Ich kann auch ein XHR in der Web-App haben, um die Sperre zu aktualisieren, wenn es sich als vorteilhaft herausgestellt hat.
Kann mir jemand dazu Gedanken geben? Klingt wie eine gute Art, Dinge zu tun? Klang wie ein schrecklicher Weg? Fertig vorher? Ich würde gerne etwas Feedback hören.
Danke! J
Ich denke nicht, da das UPDATE durch eine andere Datenbankverbindung als eine Web-App auftreten wird. Oder gar nicht, wie schon wieder .. es ist eine Web-App :-) Wenn ich etwas falsch verstehe, lass es mich wissen ... –
p.s. Wenn Sie eine Alternative zu einer separaten locked_records-Tabelle verwenden möchten, dann denke ich, dass das funktionieren würde und eleganter wäre, aber die "records" -Tabelle wird ständig von nicht bearbeitenden Benutzern gelesen und ich möchte nicht sperren aus diesem Grund. –
Die Möglichkeit, dass eine andere DB-Verbindung verwendet werden könnte, müsste evaluiert werden; Sie haben Recht, dass ein SELECT FOR UPDATE in diesem Szenario nicht funktioniert. Ein SELECT für UPDATE sollte den Zugriff von Lesern in den meisten RDBMS nicht verhindern, Sie müssten die Dokumente für Ihren lesen. – Karl