Я не могу понять, как сказать рельсам SELECT ... FOR UPDATE
в нескольких рядах. Выглядывая в консоли, Foo.where(bar: "baz").lock
выдает правильное значение SQL. Но когда я пытаюсь сделать это в транзакции, этот код ruby фактически не генерирует SQL. Я думаю, что одноразовый работает, потому что консоль rails автоматически запускает .all
в отношении для отображения результатов.
Вот что я запускаю в консоли
Foo.transaction do
Foo.where(bar: "baz").lock
Foo.where(bar: "baz").update_all(bar: "baz2")
end
и SQL:
BEGIN
Foo Update All (0.5ms) UPDATE "foos" SET "bar" = $1 WHERE "foos"."bar = $1 [["bar", "baz2"]]
COMMIT
Если я изменю линию блокировки так, чтобы rails думала, что нужно что-то сделать с коллекцией, например, добавить puts
в начало или pluck
в конец ...
Foo.where(bar: "baz").lock.pluck(:id)
... затем я получаю ожидаемый запрос FOR UPDATE
до того, как произойдет обновление, за счет того, что приходится передавать результат по проводам и помещать его в память, а затем ничего с ним не делать.
Таким образом, похоже, что rails правильно использует .lock
для изменения SQL отношения, но не существует элегантного способа фактически вызвать блокировку. Я делаю что-то не так или нам нужно использовать какой-то обходной путь (например, pluck
) для выполнения запроса?