【发布时间】:2020-04-11 10:23:44
【问题描述】:
我希望嵌套事务使父事务失败。
假设我有以下模型
class Task < ApplicationRecord
def change_status(status, performed_by)
ActiveRecord::Base.transaction do
update!(status: status)
task_log.create!(status: status, performed_by: performed_by)
end
end
end
我一直希望 update 和 task_log 创建是一起执行的事务,或者根本不执行。
如果我有一个控制器可以让我更新多个任务
class TaskController < ApplicationController
def close_tasks
tasks = Task.where(id: params[:_json])
ActiveRecord::Base.transaction do
tasks.find_each do |t|
t.change_status(:close, current_user)
end
end
end
end
我希望如果任何change_status 失败,整个请求都会从父级事务回滚。
但是,这不是 Rails 中的预期行为,请参阅 Nested Transactions 上的文档
他们举了两个例子。
User.transaction do
User.create(username: 'Kotori')
User.transaction do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
这将创建Users“Kotori”和“Nemu”,因为父级永远不会看到加薪
那么下面的例子:
User.transaction do
User.create(username: 'Kotori')
User.transaction(requires_new: true) do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
只创建“Kotori”,因为只有嵌套事务失败。
那么我怎样才能让 Rails 了解嵌套事务是否失败,从而使父事务失败。继续上面的示例,我希望它不会创建“Kotori”和“Nemu”。
【问题讨论】:
标签: ruby-on-rails activerecord ruby-on-rails-5