aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/associations/builder/collection_association.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/transaction.rb16
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb6
-rw-r--r--activerecord/lib/active_record/middleware/database_selector.rb6
-rw-r--r--activerecord/lib/active_record/touch_later.rb1
-rw-r--r--activerecord/lib/active_record/transactions.rb16
9 files changed, 37 insertions, 30 deletions
diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb
index e53665ce82..e78d25441b 100644
--- a/activerecord/lib/active_record/associations/builder/collection_association.rb
+++ b/activerecord/lib/active_record/associations/builder/collection_association.rb
@@ -22,9 +22,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
def self.define_extensions(model, name, &block)
if block_given?
- extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
+ extension_module_name = "#{name.to_s.camelize}AssociationExtension"
extension = Module.new(&block)
- model.module_parent.const_set(extension_module_name, extension)
+ model.const_set(extension_module_name, extension)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb b/activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb
index 52a796b926..d6dbef3fc8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb
@@ -8,15 +8,15 @@ module ActiveRecord
end
def create_savepoint(name = current_savepoint_name)
- execute("SAVEPOINT #{name}")
+ execute("SAVEPOINT #{name}", "TRANSACTION")
end
def exec_rollback_to_savepoint(name = current_savepoint_name)
- execute("ROLLBACK TO SAVEPOINT #{name}")
+ execute("ROLLBACK TO SAVEPOINT #{name}", "TRANSACTION")
end
def release_savepoint(name = current_savepoint_name)
- execute("RELEASE SAVEPOINT #{name}")
+ execute("RELEASE SAVEPOINT #{name}", "TRANSACTION")
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
index c9e84e48cc..7b6321d83b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
@@ -98,9 +98,13 @@ module ActiveRecord
end
def rollback_records
- ite = records.uniq
+ ite = records.uniq(&:object_id)
+ already_run_callbacks = {}
while record = ite.shift
- record.rolledback!(force_restore_state: full_rollback?)
+ trigger_callbacks = record.trigger_transactional_callbacks?
+ should_run_callbacks = !already_run_callbacks[record] && trigger_callbacks
+ already_run_callbacks[record] ||= trigger_callbacks
+ record.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: should_run_callbacks)
end
ensure
ite.each do |i|
@@ -113,10 +117,14 @@ module ActiveRecord
end
def commit_records
- ite = records.uniq
+ ite = records.uniq(&:object_id)
+ already_run_callbacks = {}
while record = ite.shift
if @run_commit_callbacks
- record.committed!
+ trigger_callbacks = record.trigger_transactional_callbacks?
+ should_run_callbacks = !already_run_callbacks[record] && trigger_callbacks
+ already_run_callbacks[record] ||= trigger_callbacks
+ record.committed!(should_run_callbacks: should_run_callbacks)
else
# if not running callbacks, only adds the record to the parent transaction
connection.add_transaction_record(record)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 282b2b1838..d239ecff89 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -204,7 +204,7 @@ module ActiveRecord
end
def begin_db_transaction
- execute "BEGIN"
+ execute("BEGIN", "TRANSACTION")
end
def begin_isolated_db_transaction(isolation)
@@ -213,11 +213,11 @@ module ActiveRecord
end
def commit_db_transaction #:nodoc:
- execute "COMMIT"
+ execute("COMMIT", "TRANSACTION")
end
def exec_rollback_db_transaction #:nodoc:
- execute "ROLLBACK"
+ execute("ROLLBACK", "TRANSACTION")
end
def empty_insert_statement_value(primary_key = nil)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
index d872bd662f..45ec79ca78 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
@@ -145,7 +145,7 @@ module ActiveRecord
# Begins a transaction.
def begin_db_transaction
- execute "BEGIN"
+ execute("BEGIN", "TRANSACTION")
end
def begin_isolated_db_transaction(isolation)
@@ -155,12 +155,12 @@ module ActiveRecord
# Commits a transaction.
def commit_db_transaction
- execute "COMMIT"
+ execute("COMMIT", "TRANSACTION")
end
# Aborts a transaction.
def exec_rollback_db_transaction
- execute "ROLLBACK"
+ execute("ROLLBACK", "TRANSACTION")
end
private
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb
index 46ce1a15b5..73b80e8c15 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb
@@ -68,15 +68,15 @@ module ActiveRecord
alias :exec_update :exec_delete
def begin_db_transaction #:nodoc:
- log("begin transaction", nil) { @connection.transaction }
+ log("begin transaction", "TRANSACTION") { @connection.transaction }
end
def commit_db_transaction #:nodoc:
- log("commit transaction", nil) { @connection.commit }
+ log("commit transaction", "TRANSACTION") { @connection.commit }
end
def exec_rollback_db_transaction #:nodoc:
- log("rollback transaction", nil) { @connection.rollback }
+ log("rollback transaction", "TRANSACTION") { @connection.rollback }
end
diff --git a/activerecord/lib/active_record/middleware/database_selector.rb b/activerecord/lib/active_record/middleware/database_selector.rb
index b5b5df074c..93a1a39c3e 100644
--- a/activerecord/lib/active_record/middleware/database_selector.rb
+++ b/activerecord/lib/active_record/middleware/database_selector.rb
@@ -35,10 +35,10 @@ module ActiveRecord
# config.active_record.database_resolver = MyResolver
# config.active_record.database_resolver_context = MyResolver::MySession
class DatabaseSelector
- def initialize(app, resolver_klass = Resolver, context_klass = Resolver::Session, options = {})
+ def initialize(app, resolver_klass = nil, context_klass = nil, options = {})
@app = app
- @resolver_klass = resolver_klass
- @context_klass = context_klass
+ @resolver_klass = resolver_klass || Resolver
+ @context_klass = context_klass || Resolver::Session
@options = options
end
diff --git a/activerecord/lib/active_record/touch_later.rb b/activerecord/lib/active_record/touch_later.rb
index b60cc96165..6872b7844e 100644
--- a/activerecord/lib/active_record/touch_later.rb
+++ b/activerecord/lib/active_record/touch_later.rb
@@ -18,6 +18,7 @@ module ActiveRecord
surreptitiously_touch @_defer_touch_attrs
add_to_transaction
+ @_new_record_before_last_commit ||= false
# touch the parents as we are not calling the after_save callbacks
self.class.reflect_on_all_associations(:belongs_to).each do |r|
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 9e03deede7..148bc0550c 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -333,7 +333,7 @@ module ActiveRecord
# Ensure that it is not called if the object was never persisted (failed create),
# but call it after the commit of a destroyed object.
def committed!(should_run_callbacks: true) #:nodoc:
- if should_run_callbacks && trigger_transactional_callbacks?
+ if should_run_callbacks
@_committed_already_called = true
_run_commit_without_transaction_enrollment_callbacks
_run_commit_callbacks
@@ -346,7 +346,7 @@ module ActiveRecord
# Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
# state should be rolled back to the beginning or just to the last savepoint.
def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
- if should_run_callbacks && trigger_transactional_callbacks?
+ if should_run_callbacks
_run_rollback_callbacks
_run_rollback_without_transaction_enrollment_callbacks
end
@@ -378,6 +378,11 @@ module ActiveRecord
status
end
+ def trigger_transactional_callbacks? # :nodoc:
+ (@_new_record_before_last_commit || _trigger_update_callback) && persisted? ||
+ _trigger_destroy_callback && destroyed?
+ end
+
private
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
@@ -392,10 +397,7 @@ module ActiveRecord
level: 0
}
@_start_transaction_state[:level] += 1
- remember_new_record_before_last_commit
- end
- def remember_new_record_before_last_commit
if _committed_already_called
@_new_record_before_last_commit = false
else
@@ -457,10 +459,6 @@ module ActiveRecord
self.class.connection.add_transaction_record(self)
end
- def trigger_transactional_callbacks?
- @_new_record_before_last_commit && !new_record? || _trigger_update_callback || _trigger_destroy_callback
- end
-
def has_transactional_callbacks?
!_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
end