ruby-on-rails 如何查找ActiveRecord ROLLBACK的原因

nafvub8i  于 2023-06-25  发布在  Ruby
关注(0)|答案(5)|浏览(161)

在日志中,我看到了一个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
mbyulnm0

mbyulnm01#

用“砰”的一声保存记录!'所以它会产生一个运行时错误,你就会知道它发生在哪里

f5emj3cl

f5emj3cl2#

一种方法是手动将信息写入日志。从您的控制器尝试以下操作:

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

这应该输出所有失败的验证的内容。

pgx2nnw8

pgx2nnw83#

1)禁用before_create,before_保存,before_update并检查它保存日期的位置
2)如果回滚是由其中一个方法引起的,请检查当您不打算回滚时这些方法是否返回true。
例如,如果你设置布尔字段的默认值来避免nil,你可能会这样做

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
jtoj6r0c

jtoj6r0c4#

我提出的3种方法(1种失败)是
1.在所有相关的保存、验证方法上使用活动记录上的观察者
1.打开活动记录并在触发ROLLBACKs的位置放置调试器语句,然后运行caller以查明触发错误的代码。
1.失败:覆盖活动记录方法并在异常时暂停。如果我没记错的话,这个方法不会捕获任何异常,因为保存方法被 Package 在一个事务中。
注意:只有当模式不是Rails.env.production时才启用?.在Rails 3.2.13上测试,使用ruby 1.9.3。
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

结束
注意:要在最新的Rails版本(从v.4到最新的v.6)中使用Observers,您需要将gem 'rails-observers'捆绑在Gemfile中(最好包含在:development和:test组中),将该类放在app/observers/active_record_observer.rb下,并在当前环境配置文件中注册观察者(例如:config/environments/development.rb)通过放置(或添加到)这一行:config.active_record.observers = [:active_record_observer]
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)

当rails服务器或控制台命中断点时,输入caller以获取回溯。
1.在开发模式中覆盖AR。TODO:仅覆盖if!Rails.env.production?把这个放进app/config/initializers/active_record_or_any_file_name.rb
ActiveRecord::Base.class_eval do alias_method:old_保存,:save alias_method:old_save!,:保存!def save(*args)开始puts“#{self} save”Rails.logger.info“#{self} save”old_save(*args)rescue Exception => e debugger puts e end end def save!(*args)开始Rails.logger.info“#{self}保存!“puts“#{self}保存!“old_保存!(*args)rescue Exception => e调试器将e end end end

5sxhfpxr

5sxhfpxr5#

在我的例子中,has_many关联定义为dependent: :restrict_with_error,而不是dependent: :destroy。它是在一个关注点中定义的,所以我没有立即看到它。无论如何,如果Rails告诉我们是什么导致回滚发生,那就太好了:-)

相关问题