0

RailsアプリケーションのモデルがActiveRecord::StatementInvalidをスローし始め、次のメッセージが表示されます:「Mysql :: Error:ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再開してみてください...」これを最初に処理した方法は、次のとおりです。

myModel.update/save/update_all

次のような例外をキャッチするためにラップします。

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

これに伴う問題は、更新/保存があるすべての場所でこの例外を救済する必要があることと、再試行によって2回実行されるか、さらに悪いことに無限ループに陥ることに注意する必要があることです。たとえば、コールバックのように、モデルレベルの1つの場所でこの問題に対処する方法はありますか?この時点ではまだ例外がスローされていないため、after_saveまたはafter_updateではうまくいかないようです。私はRails2.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 に答える