2013-01-18 225 views
0

我的Rails应用程序中的一个模型开始抛出ActiveRecord :: StatementInvalid这个消息:“Mysql :: Error:尝试获取锁定时发现死锁;尝试重新启动事务... “我处理这个最初的方法是,无论我有:Rails 2.3 - 在模型中处理ActiveRecord :: StatementInvalid

myModel.update/save/update_all 

我把它包起来,以捕获该异常,如:

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

这样做的问题是,我不得不到处拯救这个例外,我有一个更新/保存,我必须小心,r etry确实会做两次或更糟的事情进入无限循环。我能在模型层面的一个地方解决这个问题,就像在回调中一样吗?看来after_save或after_update不会执行这个技巧,因为此时还没有抛出异常。我在Rails 2.3.8中,所以after_commit或after_rollback不适合我。有任何想法吗?谢谢! ps:我知道有办法避免或减少mysql发生死锁的可能性,但我可以在死锁发生后重新启动事务,因为在我的情况下,死锁不会经常发生

+0

尤其是,如果有一种方法做MySQL的建议会很有趣:“请尝试重新启动交易”。也许重写我的模型的保存和更新方法? – Nonos

回答

0

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

class ApplicationController < ActionController::Base 

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


    protected 

    def my_custom_error_handler(exception) 
     ... 
    end 
end 

但我不知道这是否会妥善处理您重试。值得一试。让我知道!

+0

好主意。正如你所说的问题是如何处理它。一个想法可能是重新提交mysql语句,因为它包含在异常消息中,所以它实际上看起来像“Mysql :: Error:尝试获取锁时发现的死锁;尝试重新启动事务:UPDATE XXX SET YYY WHERE ZZZ)可以解析异常消息来查找mysql语句并重新提交它,但我不确定这是否是最干净的解决方案:) – Nonos

相关问题