(?) database lock (?) in rails
Let's say I have this method:
def create_registration_unless_over_limit
if Registration.count < 50
Registration.create!
else
raise "too many registrations"
end
end
How can I ensure that I never have> = 50 registrations given that I have more than one rail running? In theory, it is not possible that two requests arrive almost at the same time, both run an if statement and see <50 registrations are true, and then both create a new registration?
source to share
In your particular case, just ignore the problem :) I'm 99.99% sure you don't care if you have 50 or 51 registrations :) More generally, you need to use some kind of locking.
SELECT count(*) FROM registrations FOR UPDATE
the above request will block if another thread has executed it and is still inside a transaction.
Unfortunately, ActiveRecord :: Base's counting method does not support the: lock (hmm, why?) Parameter. Therefore you need to use count_by_sql. Try the following on two separate terminal screens:
./script/runner 'Registration.transaction {puts "counting...";c = Registration.count_by_sql("select count(*) from registrations for update");puts "count = #{c}. press enter to continue";gets}'
while the first one that starts will stop at the "press enter" stage, the second one should block at the "counting ..." stage until you release the 1st.
source to share