когда пессимистический замок выпущен в рельсах? - PullRequest
14 голосов
/ 08 июля 2010

Предполагается, что я делаю что-то вроде этого (из Руководства по запросам Active Record )

Item.transaction do  
  i = Item.first(:lock => true)  
  i.name = 'Jones'  
  i.save 
end 

Блокировка автоматически снимается в конце транзакции? Я посмотрел руководство по активным запросам и ActiveRecord :: Locking :: Pessimistic docs и не смог найти, где прямо указано, где снята блокировка.

Ответы [ 4 ]

24 голосов
/ 08 июля 2010

Блокировка - это не функция рельсов, а просто добавление оператора блокировки в запрос, который будет зависеть от используемой вами базы данных.Пессимистическая блокировка принимает «пессимистический» взгляд, полагая, что каждый запрос подвержен коррупции.Таким образом, он будет блокировать выбранные строки до тех пор, пока вы не закончите транзакцию .так что Lock> query> unlock.Несмотря на то, что это довольно непротиворечивая база данных для базы данных, было бы неплохо прочитать документацию базы данных, которую вы используете для любых специфических для базы данных вещей, которые вы должны знать.

Вот хороший раздел о оптимистической и пессимистической блокировкахэто объясняет это лучше, чем я. Оптимистическая и пессимистическая блокировки

5 голосов
/ 17 декабря 2010

Да, блокировка автоматически снимается в конце транзакции, потому что этот вид блокировки применим только к транзакциям.Не имеет смысла блокировать запись таким способом (пессимистическая блокировка) вне транзакции.

Пессимистические блокировки применяются на уровне БД.

Ниже приводится описание с примерами для mysql: http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html

0 голосов
/ 01 июля 2019

Я признал проблему с пессимистической блокировкой внутри транзакции во время тестов rspec. По какой-то причине в разных системах (я обнаружил это из-за того, что CI не смог запустить spec) запись все еще заблокирована и не может быть получена.

Итак, код и пример rspec приведены ниже.

class FooBar
  def foo
    Model.with_lock do
      model.update(bar: "baz")
    end
  end
end

красный пример

it "updates with lock" do
  expect { Foobar.foo }.to change { model.reload.bar }.to("baz")
end

но правильно зеленый пример должен выглядеть следующим образом

it do "updates with lock" do
  Foobar.foo
  expect(model.reload.bar).to eq("baz")
end
0 голосов
/ 08 июля 2010

Полагаю, вы захотите, чтобы блок «гарантировать» был уверен, что блокировка снята.

http://ruby -doc.org / core / classes / Mutex.src / M000916.html имеет:

  def synchronize
    lock
    begin
      yield
    ensure
      unlock
    end
  end

http://yehudakatz.com/2010/02/07/the-building-blocks-of-ruby/, однако, предполагает, что блочная структура этого метода автоматически разблокируется.

...