2009-05-31 6 views
0

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:

  1. Ein Benutzer lädt bis Datensatz 321 für die Bearbeitung
  2. Benutzer B Lasten bis Datensatz 321 für die Bearbeitung
  3. vorträgt Benutzer B Änderungen (sie werden in der DB gespeichert)
  4. 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

Antwort

0

Was ist mit der internen RDBMSes-Liste der Sperren? Würde es eine Option sein, die SELECT-Anweisung zu SELECT FOR UPDATE zu ändern?

+0

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 ... –

+0

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. –

+0

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

0

Eine andere Idee: Diese Datensätze haben zwei zusätzliche Spalten: assigned_to und abgeschlossen.

Wenn jemand will, um einen Datensatz bearbeiten, so etwas wie

update records set assigned_to = ? # assigning to 'me' 
where assigned_to is null 
and completed = false 
limit 1 # only assign one record at a time 

Dann diese Zeile zurück:

select ... 
from records 
where assigned_to = ? # assigned to 'me' 
and completed = false 

Und wenn Sie Ihnen den auf ‚true abgeschlossenen Satz getan ".

Sie könnten eine zusätzliche Zeitstempelspalte für die Zuordnung eines Datensatzes zu einer Person haben und dann eine ODER-Alternative zum Teil "assigned_to is null" der where-Klausel in der oben genannten update-Anweisung hinzufügen, wenn Sie eine bestimmte recensy benötigen damit eine Zuweisung gültig ist.

Verwandte Themen