简体   繁体   中英

Rails 2.3 - Handling ActiveRecord::StatementInvalid within the model

A model in my Rails application started throwing ActiveRecord::StatementInvalid with this message: "Mysql::Error: Deadlock found when trying to get lock; try restarting transaction ..." The way I handled this at first is wherever I have:

myModel.update/save/update_all

I wrap it to catch that exception like:

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

The problem with this is that I have to rescue this exception everywhere I have an update/save and that I have to be careful that the retry does do things twice or even worse go into an infinite loop. Is the a way I can address this issue in one spot on the model level like in a callback for example? It seems that an after_save or after_update won't do the trick since the exception wouldn't have been thrown at this point yet. I'm in Rails 2.3.8 so an after_commit or after_rollback is not an option for me. Any ideas? Thanks! ps: I know there are ways to avoid or reduce the chances of mysql getting a deadlock but I'm ok with just restarting the transaction after the deadlock happens since in my case the deadlock doesn't happen too often

Maybe you can try a 'rescue_from' in your ApplicationController, like the following:

class ApplicationController < ActionController::Base

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


    protected

    def my_custom_error_handler(exception)
      ...
    end
end

But I'm not sure if it will handle your retry properly. Worth a try. Let me know!

我想我会和这个宝石一起解决死锁问题https://github.com/mperham/deadlock_retry

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM