Ich bin skidish dies als eine Antwort zu geben, aber es klingt wie Sie nur eine Sperre brauchen, ist. Ändern Sie Ihre Tabelle so, dass sie eine Spalte mit dem Namen "owned_by" (oder etwas Ähnliches) enthält.
Jedes Mal, wenn die Instanz einen Datensatz ändern muss, hat es ein Update wie diese Ausgabe:
UPDATE table_name SET owned_by = IF(owned_by IS NULL, 'uniq_id', owned_by) WHERE id = 1;
Die IF-Anweisung hält sie stehlen das Schloss, wenn es zwischen den Prüfungen eingesperrt wurde.
Dann requery für die Zeile, und wenn die uniq_id auf die aktuellen Threads uniq_id festgelegt ist, dann wissen Sie, dass Sie sicher sind zu schreiben, andernfalls müssen sie in Schritten und requery schlafen, bis die Datensätze freizugeben. Wenn etwas ohne eine Sperre durchgeführt werden kann, muss dieses Feld ignoriert werden. Der Arbeitsablauf könnte so aussehen (sudo code):
def uniq_id
rand() #probably want something better here
end
def trylock_row
"UPDATE table_name SET owned_by = IF(owned_by IS NULL, '#{uniq_id}', owned_by) WHERE id = #{id};"
end
def release_lock
"UPDATE table_name SET owned_by = IF(owned_by == '#{uniq_id}', NULL, owned_by) WHERE id = #{id};"
end
def reget_row
"SELECT * FROM table_name WHERE id = #{id}"
end
def issue_update something
r = self
while(r.owned_by != uniq_id){
if r.owned_by.nil?
trylock_row
r = reget_row
break if r.owned_by == uniq_id
end
sleep(0.25) #arbitrary, keep it small
r = reget_row
}
#issue_updates
release_lock #Really should be in a ensure block just in case
end