aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
diff options
context:
space:
mode:
authorEugene Kenny <elkenny@gmail.com>2018-08-13 16:51:54 +0100
committerEugene Kenny <elkenny@gmail.com>2018-08-13 16:51:54 +0100
commit0ac81ee6ff3d1625fdbcc40b12c00cbff2208077 (patch)
tree525e64b50d3eaa9e0d545f170510ae1b9ffd67b1 /activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
parentf2970a08b57ebcdb9cbf8eec5d10a7f04eb7b9d3 (diff)
downloadrails-0ac81ee6ff3d1625fdbcc40b12c00cbff2208077.tar.gz
rails-0ac81ee6ff3d1625fdbcc40b12c00cbff2208077.tar.bz2
rails-0ac81ee6ff3d1625fdbcc40b12c00cbff2208077.zip
Omit BEGIN/COMMIT statements for empty transactions
If a transaction is opened and closed without any queries being run, we can safely omit the `BEGIN` and `COMMIT` statements, as they only exist to modify the connection's behaviour inside the transaction. This removes the overhead of those statements when saving a record with no changes, which makes workarounds like `save if changed?` unnecessary. This implementation buffers transactions inside the transaction manager and materializes them the next time the connection is used. For this to work, the adapter needs to guard all connection use with a call to `materialize_transactions`. Because of this, adapters must opt in to get this new behaviour by implementing `supports_lazy_transactions?`. If `raw_connection` is used to get a reference to the underlying database connection, the behaviour is disabled and transactions are opened eagerly, as we can't know how the connection will be used. However when the connection is checked back into the pool, we can assume that the application won't use the reference again and reenable lazy transactions. This prevents a single `raw_connection` call from disabling lazy transactions for the lifetime of the connection.
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb7
1 files changed, 7 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index a4748dbeda..359cc54cf8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -80,6 +80,8 @@ module ActiveRecord
attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
alias :in_use? :owner
+ set_callback :checkin, :after, :enable_lazy_transactions!
+
def self.type_cast_config_to_integer(config)
if config.is_a?(Integer)
config
@@ -338,6 +340,10 @@ module ActiveRecord
false
end
+ def supports_lazy_transactions?
+ false
+ end
+
# This is meant to be implemented by the adapters that support extensions
def disable_extension(name)
end
@@ -449,6 +455,7 @@ module ActiveRecord
# This is useful for when you need to call a proprietary method such as
# PostgreSQL's lo_* methods.
def raw_connection
+ disable_lazy_transactions!
@connection
end