Лок на запись
October 27, 2014

Бывает, что при обновлении строчки в базе хочется сделать серию сложных операций с зависимыми записями и желательно, чтобы паралельные потоки в это время не мешали.
В PostgreSQL есть замечательный способ блокировки SELECT FOR UPDATE
, который мне как-то подсказал Иван.
Если запустить 2 транзакции и в обеих вызвать SELECT FOR UPDATE
, то вторая транзакция будет ожидать окончания первой.
В Рейсл такие запросы удобно упакованы в методе with_lock
.
class User < ActiveRecord::Base
def do_some_tricky_calculations
with_lock do
self.name = "Tricky Dude"
# update a lot different records
save!
end
end
end
В логах мы увидем такой же FOR UPDATE
, как мы это делали вручную:
Как и в любой хорошем приеме, здесь нужна мера. Если блокировать базу часто и надолго, то производительность упадет сильно.
Tweet