ProgramingTip

ActiveRecord ROLLBACK의 원인을 찾는 방법

bestdevel 2020. 12. 6. 21:53
반응형

ActiveRecord ROLLBACK의 원인을 찾는 방법


로그 ROLLBACK는 기록되지 않습니다. ROLLBACK의 원인을 해결하는 방법이 있습니까?

로그에서 발췌 한 내용은 다음과 같다.

  Phone Load (0.4ms)  SELECT "phones".* FROM "phones" WHERE "phones"."id" = $1 LIMIT 1  [["id", 980190963]]
   (0.2ms)  BEGIN
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."phone_id" = 980190963 LIMIT 1
   (0.2ms)  ROLLBACK
  Phone Load (0.4ms)  SELECT "phones".* FROM "phones" WHERE "phones"."id" = $1 LIMIT 1  [["id", 980190963]]
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."phone_id" = 980190963 LIMIT 1

BANG '!'로 기록 저장 실행 런타임 오류가 발생하고 어디서 발생하는지 알 수 있습니다.


한 가지 방법은 로그에 정보를 수동으로 쓰는 것입니다. 컨트롤러에서 다음과 같이 시도하십시오.

Rails.logger.info(@your_object.errors.inspect) 

실패한 모든 유효성 검사의 내용을 출력해야합니다.


1) before_create, before_save, before_update를 비활성화 하고 하루를 저장하는 위치를 확인하십시오.

2) 확실한 방법 중 하나에 의해 롤백이 경우 롤백을 계획하지 않을 때 해당 메소드가 반환되는지 확인합니다.

예를 들어 nil을 피하기 위해 boolean 필드의 전화를 설정하고 아마도 이렇게 할 것입니다.

def set_defaults_before_create
  self.my_boolean_field ||= false
end

이 예제에서 set_defaults_before_create 메소드 는 항상 false를 반환 하는 트랜잭션을 롤백합니다. 따라서 리팩터링하여 true를 반환하십시오.

def set_defaults_before_create
  self.my_boolean_field ||= false
  true
end

내가 생각 해낸 3 가지 방법론 (1 개 실패)은 다음과 같다.

1) 모든 관련 저장, 유효성 검사 방법의 활성 레코드에 관찰 유효성 검사를 사용합니다.

2) 활성 레코드를 ROLLBACK이 트리거되는 디버거 문을 넣은 다음 실행 caller하여 오류를 트리거 한 코드를 정확히 찾습니다.

3) 실패 : 활성 기록 방법을 무시하고 예외 발생시 일시 중지합니다. 이 메소드는 저장 메소드가 트랜잭션에 래핑되어 있기 때문에 예외를 발생시키지 않습니다.

참고 : 모드가 Rails.env.production?이 아닌 경우에만 활성화하십시오. 루비 1.9.3을 사용하여 Rails 3.2.13에서 테스트했습니다.

1) 관찰자 : http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#observers

class ActiveRecordObserver < ActiveRecord::Observer

    observe "ActiveRecord::Base"

    def after_validation(model)
        debugger if model.errors.messages.any?
        Rails.logger.error "after validation"
    end
    def before_update(model)
        debugger if !model.valid?
        Rails.logger.error "before update"
    end
    def after_update(model)
        debugger if !model.valid?
        Rails.logger.error "after update"
    end
    def before_save(model)

        debugger if model.errors.messages.any?
        Rails.logger.error "#{model}" Rails.logger.error "before save"
    end
    def after_save(model)
        debugger if model.errors.messages.any?
        Rails.logger.error "after save"
    end
end

2) https://github.com/rails/rails/blob/3-1-stable/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L231 cd`bundle show activerecord`

     Put a debugger statement when where the rollback is executed.
    /Users/<user>/.rvm/gems/ruby-1.9.3-<env>/gems/activerecord-3.2.14/lib/active_record/connection_adapters/abstract/database_statements.rb

   196              transaction_open = false
   197              decrement_open_transactions
   198              if open_transactions == 0
   199                rollback_db_transaction
   200                debugger
=> 201                rollback_transaction_records(true)
   202              else
   203                rollback_to_savepoint
   204                debugger
   205                rollback_transaction_records(false)

레일스 서버 또는 콘솔 caller이 역 추적을 위해 중단 점 유형에 도달 할 때.

3) 개발 모드에서 AR을 재정의합니다. 할 것 :! Rails.env.production? 넣어 넣어app/config/initializers/active_record_or_any_file_name.rb

ActiveRecord::Base.class_eval do
    alias_method :old_save, :save
    alias_method :old_save!, :save!
    def save(*args)
        begin
            puts "#{self} save"
            Rails.logger.info "#{self} save"
            old_save(*args)
        rescue Exception => e
            debugger
            puts e
        end
    end
    def save!(*args)
        begin
            Rails.logger.info "#{self} save!"
            puts "#{self} save!"
            old_save!(*args)
        rescue Exception => e
            debugger
            puts e
        end
    end
end

참고 URL : https://stackoverflow.com/questions/9060014/how-to-find-the-cause-of-activerecord-rollback

반응형