Can I do atomic increments in Rails 2.3 without abandoning SQL?

In our application, there is a code with frequent clicks that increases the column like this:

if (r = customer.find_or_generate_reminder)
  r.counter += 1
  r.save!
end

We get lock wait timeouts, so I'm thinking of making this an atomic operation. Naively, what I want to do is:

if (r = customer.find_or_generate_reminder)
  connection.excute('UPDATE customer_reminders SET counter=counter+1, updated_at=now() WHERE id = ' + r.id)
end

Is there a way for the ruby ​​world to do the same?

+5
source share
3 answers

You can use the class method increment_counter:

Customer.increment_counter :counter, customer

This will create something like:

UPDATE `customers` SET `counter` = COALESCE(`counter`, 0) + 1 WHERE (`customers`.`id` = 53)

(you must pass either id or an instance of the class to this method ( customer) as opposed to a method customer.increment!(:counter)that is not atomic)

+7
source

, -:

https://github.com/imme5150/rails_atomic_increment

:

customer.atomic_increment!( :counter )

, .

+1

If you don't mind a bit of SQL:

CustomerReminder.where(id: id).update_all('counter = counter + 1, updated_at = now()')
0
source

All Articles