Rails 中的事务块一次性更新/保存模型的多个实例?
我想更新数百条记录的值;每条记录的值都不同。这不是一个属性的大规模更新情况。Model.update_all(attr:值)在这里不合适。
MyModel.transaction do
things_to_update.each do |thing|
thing.score = rand(100) + rand(100)
thing.save
end
end
save
似乎发出自己的事务,而不是将更新批处理到周围的事务中。我希望所有更新都集中在一个大事务中。
我怎样才能做到这一点?
假设您知道要将 ID 为 1、2 和 3 的内容设置为分数、2、8 和 64(而不仅仅是随机数),您可以:
UPDATE
things AS t
SET
score = c.score
FROM
(values
(1, 2),
(2, 30),
(4, 50)
) as c(id, score)
where c.id = t.id;
因此,对于 Rails,您将使用 ActiveRecord::Base.connection#execute
来执行类似于上述的块,但插入了正确的值字符串。
我不确定,但您可能将多个事务与多个查询混淆了。
您发布的代码将创建一个事务(例如,如果发生异常,则所有更新都将回滚),但每个save
都会导致单独的更新查询。
如果可以使用SQL而不是Ruby代码执行更新,那么这可能是最好的方法。
我认为您只需将方法"保存"更改为"保存!如果任何更新失败,该方法保存!生成异常。当事务块中发生异常时,事务将反转整个操作(回滚)
MyModel.transaction do
things_to_update.each do |thing|
thing.score = rand(100) + rand(100)
thing.save!
end