0

我的 Rails 应用程序中的一个模型开始抛出 ActiveRecord::StatementInvalid 并显示以下消息:“Mysql::Error: Deadlock found when trying to get lock; try restarting transaction ...” 我一开始处理这个问题的方式是:

myModel.update/save/update_all

我将它包装起来以捕获该异常,例如:

begin
  myModel.update_all(..) 
rescue Exception => e
  if e.message.include?("Deadlock")
    retry
  end
end

这样做的问题是,我必须在有更新/保存的任何地方拯救这个异常,并且我必须小心重试会做两次事情,甚至更糟的是进入无限循环。我可以在模型级别的一个位置解决这个问题,例如在回调中吗?似乎 after_save 或 after_update 不会起作用,因为此时还没有抛出异常。我在 Rails 2.3.8 中,所以 after_commit 或 after_rollback 对我来说不是一个选项。有任何想法吗?谢谢!ps:我知道有一些方法可以避免或减少mysql出现死锁的机会,但我可以在死锁发生后重新启动事务,因为在我的情况下,死锁不会经常发生

4

2 回答 2

0

也许您可以在 ApplicationController 中尝试“rescue_from”,如下所示:

class ApplicationController < ActionController::Base

    rescue_from ActiveRecord::StatementInvalid, :with => :my_custom_error_handler


    protected

    def my_custom_error_handler(exception)
      ...
    end
end

但我不确定它是否会正确处理您的重试。值得一试。让我知道!

于 2013-01-18T20:25:17.907 回答
0

我想我会用这个 gem 来解决死锁问题 https://github.com/mperham/deadlock_retry

于 2013-01-18T21:08:30.803 回答