我们在out_logs控制器中有以下代码,用于在 rails 3.1.3 应用程序中保存到两个表中。为了确保两次节省完成或无完成,使用事务。
@out_log.transaction do
if @out_log.save && @part.save
redirect_to part_path(@part), :notice => "Saved!"
else
flash.now[:error] = "Not saved!"
render 'new'
end
end
代码似乎有效。我们的问题是:
- 上面的代码是交易的良好做法吗?
- 事务循环中有redirect_to和渲染,这些redirect_to或渲染是否会增加事务循环的执行时间,从而锁定数据库(我们使用sqlite3)太久?
非常感谢。
首先:redirect_to
或render
不像一个return
语句。他们只是在当前正在准备的响应中分配一些标头。
关于交易:
if @out_log.save && @part.save
上面的代码肯定会导致数据库中的状态不一致:如果第一个save
成功而第二个成功怎么办?甚至很难想象。
解决方案非常简单:使用save!
(末尾带有感叹号)。这样,如果验证失败,整个事务将被回滚(save!
将引发异常,而不是像save
那样返回false
)。