aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorBrent Wheeldon <brent.wheeldon@gmail.com>2017-11-02 14:53:43 -0400
committerBrent Wheeldon <brent.wheeldon@gmail.com>2017-11-09 10:46:01 -0500
commit1f9f6f6cfc57020ccb35f77872c56f069f337075 (patch)
tree0bcd80358ffba33786a77af6134ecbd436bcf03a /activerecord
parenteae65ac2ab7e7a8155fa5a76c15f21cee09499c2 (diff)
downloadrails-1f9f6f6cfc57020ccb35f77872c56f069f337075.tar.gz
rails-1f9f6f6cfc57020ccb35f77872c56f069f337075.tar.bz2
rails-1f9f6f6cfc57020ccb35f77872c56f069f337075.zip
Prevent deadlocks with load interlock and DB lock.
This fixes an issue where competing threads deadlock each other. - Thread A holds the load interlock but is blocked on getting the DB lock - Thread B holds the DB lock but is blocked on getting the load interlock (for example when there is a `Model.transaction` block that needs to autoload) This solution allows for dependency loading in other threads while a thread is waiting to acquire the DB lock. Fixes #31019
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb3
1 files changed, 2 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index e3aab8dad8..e91ef3b779 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -6,6 +6,7 @@ require "active_record/connection_adapters/schema_cache"
require "active_record/connection_adapters/sql_type_metadata"
require "active_record/connection_adapters/abstract/schema_dumper"
require "active_record/connection_adapters/abstract/schema_creation"
+require "active_support/concurrency/load_interlock_aware_monitor"
require "arel/collectors/bind"
require "arel/collectors/composite"
require "arel/collectors/sql_string"
@@ -108,7 +109,7 @@ module ActiveRecord
@schema_cache = SchemaCache.new self
@quoted_column_names, @quoted_table_names = {}, {}
@visitor = arel_visitor
- @lock = Monitor.new
+ @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
@prepared_statements = true