Могу ли я сделать атомарный прирост в Rails 2.3, не переходя на SQL? - PullRequest
5 голосов
/ 02 февраля 2011

В нашем приложении есть несколько часто используемых кодов, которые увеличивают столбец, например:

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

У нас тайм-ауты ожидания блокировки, поэтому я подумываю сделать это атомарной операцией. Наивно то, что я хочу сделать, выглядит так:

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

Есть ли способ в рубиновом мире сделать то же самое?

Ответы [ 3 ]

7 голосов
/ 02 февраля 2011

Вы можете использовать метод класса increment_counter:

Customer.increment_counter :counter, customer

Это создаст что-то вроде:

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

(вы должны передать в этот метод идентификатор или экземпляр класса (customer) в отличие от customer.increment!(:counter) метода, который не является атомарным)

1 голос
/ 22 ноября 2011

Я создал камень, чтобы сделать его более объектно-ориентированным:

https://github.com/imme5150/rails_atomic_increment

Позволяет вам:

customer.atomic_increment!( :counter )

Дайте мне знать, что вы думаете.

0 голосов
/ 20 мая 2015

Если вы не возражаете против SQL:

CustomerReminder.where(id: id).update_all('counter = counter + 1, updated_at = now()')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...