如何让 rails select 更新多行?
How can I have rails select for update on multiple rows?
我不知道如何在多行上告诉 rails 到 SELECT ... FOR UPDATE
。在控制台中四处寻找,Foo.where(bar: "baz").lock
确实产生了正确的 SQL。但是当我尝试在事务中执行此操作时,ruby 代码实际上并没有生成 SQL。我认为一次性有效,因为 rails 控制台自动 运行s .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" = WHERE "foos"."bar = [["bar", "baz2"]]
COMMIT
如果我更改锁定行,使 rails 认为它需要对集合做一些事情,比如将 puts
添加到开头或将 pluck
添加到结尾。 .
Foo.where(bar: "baz").lock.pluck(:id)
...然后我确实在更新发生之前得到了预期的 FOR UPDATE
查询,代价是必须通过网络传输结果并将其放入内存,然后什么都不做。
所以似乎 rails 正确地使用 .lock
来修改关系的 SQL,但是没有优雅的方法来实际调用锁。我是在做错什么,还是我们需要使用某种解决方法(例如 pluck
)来让查询发生?
ApplicationRecord.transaction do
User.where(id: [1, 2]).lock!.map do |user|
puts user.id
user.id
end
end
生产
(0.2ms) BEGIN
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2) FOR UPDATE
1
2
(0.9ms) COMMIT
=> [1, 2]
受这里讨论的启发:https://dba.stackexchange.com/questions/257188/
我认为最好的通用解决方案是
Foo.where(bar: "baz").order(:id).lock.pluck('')
哪个会产生
SELECT FROM "foos" WHERE "foos"."bar" = 'baz' ORDER BY "foos"."id" ASC FOR UPDATE;
我不知道如何在多行上告诉 rails 到 SELECT ... FOR UPDATE
。在控制台中四处寻找,Foo.where(bar: "baz").lock
确实产生了正确的 SQL。但是当我尝试在事务中执行此操作时,ruby 代码实际上并没有生成 SQL。我认为一次性有效,因为 rails 控制台自动 运行s .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" = WHERE "foos"."bar = [["bar", "baz2"]]
COMMIT
如果我更改锁定行,使 rails 认为它需要对集合做一些事情,比如将 puts
添加到开头或将 pluck
添加到结尾。 .
Foo.where(bar: "baz").lock.pluck(:id)
...然后我确实在更新发生之前得到了预期的 FOR UPDATE
查询,代价是必须通过网络传输结果并将其放入内存,然后什么都不做。
所以似乎 rails 正确地使用 .lock
来修改关系的 SQL,但是没有优雅的方法来实际调用锁。我是在做错什么,还是我们需要使用某种解决方法(例如 pluck
)来让查询发生?
ApplicationRecord.transaction do
User.where(id: [1, 2]).lock!.map do |user|
puts user.id
user.id
end
end
生产
(0.2ms) BEGIN
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2) FOR UPDATE
1
2
(0.9ms) COMMIT
=> [1, 2]
受这里讨论的启发:https://dba.stackexchange.com/questions/257188/
我认为最好的通用解决方案是
Foo.where(bar: "baz").order(:id).lock.pluck('')
哪个会产生
SELECT FROM "foos" WHERE "foos"."bar" = 'baz' ORDER BY "foos"."id" ASC FOR UPDATE;