2016-04-17 12 views
2

PGの同期が外れたとき(よく知られている問題)(example)、問題が発生しました。begin ... endなしでrescueブロックに再試行できますか?

PGの同期が失われ、IDのシーケンスがインクリメントを停止し、ActiveRecord::RecordNotUniqueエラーが発生します。

しかし、私が見つけたすべての解決策では、いくつかのマニュアル解決策が提案されています。コンソールで操作を行うか、カスタムレイクタスクを実行するかどちらかです。

しかし、これは生産には不満があります。毎回、ユーザーは500人になります。サーバーを管理している人は、その日を節約する必要があります。 (何らかの理由でテストデータによると、私の場合は頻繁に起こる可能性があります)。

私はActiveRecord Baseクラスにパッチを当てて、この特定のエラーをキャッチして救助したいと思います。

私はコントローラに時々このロジックを使用します。

class ApplicationController < ActionController::Base 

    rescue_from ActionController::ParameterMissing, ActiveRecord::RecordNotFound do |e| 
    # some logic here 
    end 
    end 

しかし、ここで私は、リトライは必要ありません。また、Base createメソッドをオーバーライドしないなど、猿のパッチ適用に深く関わりたくありません。

だから私はこのような何かを考えていた:

module ActiveRecord 
    class Base 


     rescue ActiveRecord::RecordNotUnique => e 
     if e.message.include? '_pkey' 
      table =e.message.match(//) #regex to define table 
      ActiveRecord::Base.connection.reset_pk_sequence!(table) 
      retry 
     else 
      raise 
     end 
     end 
    end 

しかし、私はRailsの/ Rubyがそれを再試行するように求め正確に理解するかどうかはわからないとして、それはおそらく、動作しません。

解決策はありますか?

P.S.手動コマンドラインコマンドなしで動作し、アンサーブユーザを持つシーケンスの全体的な問題に対する関連した解決策も評価されていません。

答えて

0

質問に答えるには、いいえ。 rescueは、ブロック本体またはメソッド本体のbegin..end内からのみ使用できます。

begin 
    bad_method 
rescue SomeException 
    retry 
end 

def some_method 
    bad_method 
rescue SomeException 
    retry 
end 

rescue_fromので、実行がコントローラであるか間接的で作成されたばかりのフレームワークのヘルパーメソッドです。

質問に答えるには、本当にと聞いてください。 create_or_updateは、rescue/retryで上書きできます。

module NonUniquePkeyRecovery 
    def create_or_update(*) 
    super 
    rescue ActiveRecord::RecordNotUnique => e 
    raise unless e.message.include? '_pkey' 
    self.class.connection.reset_pk_sequence!(self.class.table_name) 
    retry 
    end 
end 

ActiveSupport.on_load(:active_record) do 
    include NonUniquePkeyRecovery 
end 
関連する問題