RoR:在保存时挽救数据库异常的正确方法?

时间:2016-07-19 15:58:57

标签: ruby-on-rails ruby-on-rails-3 activerecord

在我尝试保存ActiveRecord模型后,我最近遇到了数据库失败 lblNewLabel.setOpaque(true); 的问题。

如果我尝试Adaptive Server connection timed out这次失败的尝试并再次保存对象,我得到rescue,所以我必须重新创建从一开始就保存的对象,这可能是一个非常昂贵的过程。

在app方面处理这种情况的正确方法是什么,因为我不能以任何方式影响数据库性能?

2 个答案:

答案 0 :(得分:0)

重新加载是你想要的

begin
  object.save
rescue
  object.reload.save
end
这样的事情。这是它的文档:

http://apidock.com/rails/ActiveRecord/Persistence/reload

答案 1 :(得分:0)

Adaptive Server connection timed out错误是由于更新记录花费的时间太长。处理这种情况的一种方法是在database.yml中增加语句超时:

timeout: 10000 # milliseconds, default is 5000

这不能直接解决问题,但可能有助于降低问题的发生频率。

Active Record Query Interface Guide中所述,乐观锁定仅在表格中存在lock_version字段时才有效。目前尚不清楚您是否首先需要锁定,但您的Rails显然已启用并正常工作。

由于lock_version的值是触发ActiveRecord::StaleObjectError的唯一内容,因此您可以在第二次保存尝试时对其进行操作。直接的方法是从数据库中查询最新值并相应地更新对象:

lock_version = Model.where(id: model.id).pluck(:lock_version).first
model.lock_version = lock_version

# then attempt to save again

model.save!

请注意,这将使用您的更改重写数据库状态,无论是否进行任何并行修改,都会破坏锁定的目的。

话虽如此,当更新超时时,locking_version会发生变化,这有点可疑。当然值得挖掘它,看看为什么会发生这种情况。至少你应该确保将更新包装在一个事务中,仅此一项就可以解决问题。