Я skidish давая это как ответ, но это звучит, как вы просто нужно, это замок. Измените таблицу, чтобы включить столбец «owned_by» (или что-то подобное).
Всякий раз, когда ваш экземпляр должен изменить запись, иметь его выпустить обновление, как это:
UPDATE table_name SET owned_by = IF(owned_by IS NULL, 'uniq_id', owned_by) WHERE id = 1;
Оператор IF удерживает его от кражи замок, если он был заперт между проверками.
Затем запрашивается строка, а если uniq_id настроен на текущие потоки uniq_id, то вы знаете, что можете безопасно писать, иначе спятите с шагом и запросом до тех пор, пока блокировка записей не будет освобождена. Если что-то можно сделать без блокировки, просто попросите его игнорировать это поле. Рабочий поток может выглядеть примерно так (код sudo):
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