【发布时间】:2020-01-09 17:06:19
【问题描述】:
我不知道如何在多行上告诉 rails 到 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)来让查询发生?
【问题讨论】:
标签: ruby-on-rails postgresql pessimistic-locking