We have problem with agreeing with a comment in Squeks. If the same user agrees on the same comment at the same time, then 2 identical records of comment_agree will be created.
Therefore, we need some kind of critical section in order to prevent that situation.
The Solution
We use Named Lock provided by MySQL. You can use these two statements:
SELECT GET_LOCK('lock1',10);
SELECT RELEASE_LOCK('lock1');
Anyway, it's more convenient to build a class in order to deal with this:
class Lock
def self.lock(name)
return ActiveRecord::Base.connection.execute("SELECT GET_LOCK('#name}',60);").fetch_row[0]
end
def self.release(name)
ActiveRecord::Base.connection.execute("SELECT RELEASE_LOCK('#{name}');")
end
def initialize(*name)
@lock_name = Lock.generate_name(name)
end
def synchronize(&block)
Lock.lock(@lock_name) rescue (raise "Getting Lock #{@lock_name} timeout")
block.call()
while true
Lock.release(@lock_name) rescue next
break
end
end
private
def self.generate_name(names)
names.map{ |t| t.to_s}.join('--')
end
end