Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I do an atomic increment in Rails 2.3 without dropping down to SQL?

We have some often-hit code in our app that increments a column, like so:

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

We're getting lock wait timeouts, so I'm thinking about making this an atomic operation. Naively, what I want to do looks like this:

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 ruby-world way of doing the same thing?

like image 300
Simon Avatar asked Feb 02 '11 09:02

Simon


1 Answers

You can use the class method increment_counter:

Customer.increment_counter :counter, customer

That'll create something like:

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

(you have to pass either an id or an instance of the class into this method (customer) unlike the customer.increment!(:counter) method which is not atomic)

like image 76
idlefingers Avatar answered Sep 23 '22 23:09

idlefingers