Я не могу понять, как указать рельсам SELECT ... FOR UPDATE
в нескольких строках. Покопавшись в консоли, Foo.where(bar: "baz").lock
действительно выдает правильный SQL. Но когда я пытаюсь сделать это в транзакции, этот рубиновый код на самом деле не генерирует 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
Если я изменю строку блокировки, чтобы рельсы думали, что нужно что-то сделать с коллекцией, например, добавить puts
в начало или pluck
в конец...
Foo.where(bar: "baz").lock.pluck(:id)
... затем я получаю ожидаемый запрос FOR UPDATE
до того, как произойдет обновление, за счет того, что мне придется передавать результат по сети и помещать его в память, а затем ничего с ним не делать.
Таким образом, кажется, что rails правильно использует .lock
для изменения SQL отношения, но нет элегантного способа фактически вызвать блокировку. Я делаю что-то не так или нам нужно использовать какой-то обходной путь (например, pluck
), чтобы выполнить запрос?