2013-01-18 224 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

相關問題