Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NameError: uninitialized constant ActiveRecord::ConnectionAdapters::DatabaseStatements::TransactionManager when calling reset_transaction #26441

Closed
synthead opened this issue Sep 9, 2016 · 8 comments
Assignees
Labels

Comments

@synthead
Copy link

@synthead synthead commented Sep 9, 2016

Saw this exception pop up. I'm not sure how or why it happened, so I can't provide steps to reproduce it, but I'm happy to try anything to help.

2016-09-09T18:12:08.225Z 8 TID-ouaqkszjs WARN: NameError: uninitialized constant ActiveRecord::ConnectionAdapters::DatabaseStatements::TransactionManager
Did you mean?  ActiveRecord::ConnectionAdapters::TransactionManager
               ActiveRecord::ConnectionAdapters::Transaction
               ActiveRecord::ConnectionAdapters::TransactionState
2016-09-09T18:12:08.236Z 8 TID-ouaqkszjs WARN: /usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/database_statements.rb:247:in `reset_transaction'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/database_statements.rb:6:in `initialize'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/query_cache.rb:24:in `initialize'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract_adapter.rb:99:in `initialize'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/postgresql_adapter.rb:209:in `initialize'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/postgresql_adapter.rb:37:in `new'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/postgresql_adapter.rb:37:in `postgresql_connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:721:in `new_connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:765:in `checkout_new_connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:744:in `try_to_checkout_new_connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:705:in `acquire_connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:501:in `checkout'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in `connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:875:in `retrieve_connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_handling.rb:128:in `retrieve_connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_handling.rb:91:in `connection'
/usr/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/query_cache.rb:47:in `block in install_executor_hooks'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:396:in `instance_exec'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:396:in `block in make_lambda'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:169:in `block (2 levels) in halting'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:547:in `block (2 levels) in default_terminator'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:546:in `catch'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:546:in `block in default_terminator'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:170:in `block in halting'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:454:in `block in call'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:454:in `each'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:454:in `call'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:101:in `__run_callbacks__'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:750:in `_run_complete_callbacks'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:90:in `run_callbacks'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/execution_wrapper.rb:107:in `complete!'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/execution_wrapper.rb:64:in `ensure in block in run!'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/execution_wrapper.rb:64:in `block in run!'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/execution_wrapper.rb:58:in `tap'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/execution_wrapper.rb:58:in `run!'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/execution_wrapper.rb:74:in `wrap'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/reloader.rb:67:in `wrap'
/usr/lib/ruby/gems/2.3.0/gems/activejob-5.0.0.1/lib/active_job/railtie.rb:25:in `block (3 levels) in <class:Railtie>'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:391:in `instance_exec'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:391:in `block in make_lambda'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:285:in `block in halting'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:447:in `block in around'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:455:in `call'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:101:in `__run_callbacks__'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:750:in `_run_execute_callbacks'
/usr/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb:90:in `run_callbacks'
/usr/lib/ruby/gems/2.3.0/gems/activejob-5.0.0.1/lib/active_job/execution.rb:20:in `execute'
/usr/lib/ruby/gems/2.3.0/gems/activejob-5.0.0.1/lib/active_job/queue_adapters/sidekiq_adapter.rb:40:in `perform'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/processor.rb:152:in `execute_job'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/processor.rb:134:in `block (2 levels) in process'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/middleware/chain.rb:128:in `block in invoke'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/middleware/chain.rb:130:in `block in invoke'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/logging.rb:32:in `with_context'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/middleware/server/logging.rb:7:in `call'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/middleware/chain.rb:130:in `block in invoke'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/middleware/chain.rb:133:in `invoke'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/processor.rb:129:in `block in process'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/processor.rb:168:in `stats'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/processor.rb:128:in `process'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/processor.rb:80:in `process_one'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/processor.rb:68:in `run'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/util.rb:17:in `watchdog'
/usr/lib/ruby/gems/2.3.0/gems/sidekiq-4.1.2/lib/sidekiq/util.rb:25:in `block in safe_thread'

Something tells me that this line...

      def reset_transaction #:nodoc:
        @transaction_manager = TransactionManager.new(self)
      end

...should probably be updated to...

      def reset_transaction #:nodoc:
        @transaction_manager = ActiveRecord::ConnectionAdapters::TransactionManager.new(self)
      end

Also, it looks like the two tests actually call TransactionManager explicitly, so I believe that the reset_transaction method doesn't have a test to catch the above exception:

  def test_transactions_state_from_rollback
    connection = Topic.connection
    transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction

    assert transaction.open?
    assert !transaction.state.rolledback?
    assert !transaction.state.committed?

    transaction.rollback

    assert transaction.state.rolledback?
    assert !transaction.state.committed?
  end

  def test_transactions_state_from_commit
    connection = Topic.connection
    transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction

    assert transaction.open?
    assert !transaction.state.rolledback?
    assert !transaction.state.committed?

    transaction.commit

    assert !transaction.state.rolledback?
    assert transaction.state.committed?
  end

System configuration

Rails version: 5.0.0.1
Ruby version: 2.3.1p112

@matthewd
Copy link
Member

@matthewd matthewd commented Sep 9, 2016

#26273 may be related

@arthurnn arthurnn self-assigned this Sep 12, 2016
@arthurnn
Copy link
Member

@arthurnn arthurnn commented Sep 12, 2016

@matthewd is this related to code reload?

@synthead
Copy link
Author

@synthead synthead commented Sep 12, 2016

If it helps to mention it, this happened in production mode.

@arthurnn
Copy link
Member

@arthurnn arthurnn commented Sep 12, 2016

@synthead does your app has any special require design? or caching on the load paths? or anything that could affect this?
I am trying to think why this happens there and not in the other runs.

@matthewd
Copy link
Member

@matthewd matthewd commented Sep 12, 2016

@arthurnn it shouldn't be -- these classes don't get unloaded. But given that something is clearly doing the wrong thing, I wouldn't rule it out.

@synthead
Copy link
Author

@synthead synthead commented Sep 15, 2016

This is in config/application.rb:

module MyApp
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Do not swallow errors in after_commit/after_rollback callbacks.
    config.active_record.raise_in_transactional_callbacks = true

    # Include ActiveJob concerns when application is eager-loaded.
    config.eager_load_paths.unshift(config.root.join("app/jobs/concerns").to_s)

    # Allow WebSocket requests from any origin.
    config.action_cable.disable_request_forgery_protection = true

    config.after_initialize do
      Rails.application.eager_load!

      ::ACTIONS_MAP = Hash.new.tap do |my_app_actions|
        ActiveJob::Base.descendants.each do |descendant|
          if descendant.included_modules.include?(MyApp)
            action = descendant.name.underscore.chomp("_job")
            my_app_actions[action] = descendant
          end
        end
      end
    end
  end
end

Think this might be causing issues? The strange thing is that it happened unexpectedly about a day after a number of Sidekiq jobs went though.

@arthurnn arthurnn closed this in f62451a Sep 16, 2016
@arthurnn
Copy link
Member

@arthurnn arthurnn commented Sep 16, 2016

I added the correct namespace, which should fix this issue. see f62451a.
I will backport that to 5-0-stable(8f3178f), so it should be available in the next 5.0 release

@synthead
Copy link
Author

@synthead synthead commented Sep 16, 2016

Awesome! Thanks so much!

arthurnn added a commit that referenced this issue Sep 23, 2016
[fixes #26441]
arthurnn pushed a commit that referenced this issue Sep 23, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants