、ありがとうございました。 '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 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