how to find the cause of ActiveRecord ROLLBACK

后端 未结 4 1857
小鲜肉
小鲜肉 2020-12-07 22:40

In the logs I\'m seeing a ROLLBACK, but no exception is logged. Is there a way to find out what caused the ROLLBACK?

Here\'s the excerpt of the log:

4条回答
  •  感情败类
    2020-12-07 22:59

    The 3 methodologies (1 failed) I have come up with are to

    1) use an observer on active record on all the relevant save, validate methods

    2) to open up active record and put a debugger statement where ROLLBACKs are triggered and then run caller to pinpoint the code that triggered the error.

    3) Failed :override the active record methods and pause on exception. If I remember this method does not catch any exception because the save methods are wrapped in a transaction.

    Notes: Only enable when the mode is not Rails.env.production?. Tested on Rails 3.2.13, using ruby 1.9.3.

    1) Observer: 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//.rvm/gems/ruby-1.9.3-/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)
    

    When the rails server or console hits the breakpoint type in caller to get the backtrace.

    3) Override AR in development mode. TODO: only override if !Rails.env.production? Put this in 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
    

提交回复
热议问题