Class: ActiveRecord::ConnectionAdapters::TransactionManager
Do not use. This class is for internal use only.
Relationships & Source Files | |
Inherits: | Object |
Defined in: | activerecord/lib/active_record/connection_adapters/abstract/transaction.rb |
Constant Summary
-
NULL_TRANSACTION =
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 666NullTransaction.new.freeze
Class Method Summary
- .new(connection) ⇒ TransactionManager constructor
Instance Attribute Summary
- #lazy_transactions_enabled? ⇒ Boolean readonly
- #restorable? ⇒ Boolean readonly
Instance Method Summary
- #begin_transaction(isolation: nil, joinable: true, _lazy: true)
- #commit_transaction
- #current_transaction
- #dirty_current_transaction
- #disable_lazy_transactions!
- #enable_lazy_transactions!
- #materialize_transactions
- #open_transactions
- #restore_transactions
- #rollback_transaction(transaction = nil)
- #within_new_transaction(isolation: nil, joinable: true)
-
#after_failure_actions(transaction, error)
private
Deallocate invalidated prepared statements outside of the transaction.
Constructor Details
.new(connection) ⇒ TransactionManager
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 498
def initialize(connection) @stack = [] @connection = connection @has_unmaterialized_transactions = false @materializing_transactions = false @lazy_transactions_enabled = true end
Instance Attribute Details
#lazy_transactions_enabled? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 557
def lazy_transactions_enabled? @lazy_transactions_enabled end
#restorable? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 573
def restorable? @stack.none?(&:dirty?) end
Instance Method Details
#after_failure_actions(transaction, error) (private)
Deallocate invalidated prepared statements outside of the transaction
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 669
def after_failure_actions(transaction, error) return unless transaction.is_a?(RealTransaction) return unless error.is_a?(ActiveRecord::PreparedStatementCacheExpired) @connection.clear_cache! end
#begin_transaction(isolation: nil, joinable: true, _lazy: true)
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 506
def begin_transaction(isolation: nil, joinable: true, _lazy: true) @connection.lock.synchronize do run_commit_callbacks = !current_transaction.joinable? transaction = if @stack.empty? RealTransaction.new( @connection, isolation: isolation, joinable: joinable, run_commit_callbacks: run_commit_callbacks ) elsif current_transaction.restartable? RestartParentTransaction.new( @connection, current_transaction, isolation: isolation, joinable: joinable, run_commit_callbacks: run_commit_callbacks ) else SavepointTransaction.new( @connection, "active_record_#{@stack.size}", current_transaction, isolation: isolation, joinable: joinable, run_commit_callbacks: run_commit_callbacks ) end unless transaction.materialized? if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && _lazy @has_unmaterialized_transactions = true else transaction.materialize! end end @stack.push(transaction) transaction end end
#commit_transaction
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 593
def commit_transaction @connection.lock.synchronize do transaction = @stack.last begin transaction.before_commit_records ensure @stack.pop end dirty_current_transaction if transaction.dirty? transaction.commit transaction.commit_records end end
#current_transaction
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 661
def current_transaction @stack.last || NULL_TRANSACTION end
#dirty_current_transaction
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 561
def dirty_current_transaction current_transaction.dirty! end
#disable_lazy_transactions!
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 548
def disable_lazy_transactions! materialize_transactions @lazy_transactions_enabled = false end
#enable_lazy_transactions!
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 553
def enable_lazy_transactions! @lazy_transactions_enabled = true end
#materialize_transactions
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 577
def materialize_transactions return if @materializing_transactions if @has_unmaterialized_transactions @connection.lock.synchronize do begin @materializing_transactions = true @stack.each { |t| t.materialize! unless t.materialized? } ensure @materializing_transactions = false end @has_unmaterialized_transactions = false end end end
#open_transactions
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 657
def open_transactions @stack.size end
#restore_transactions
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 565
def restore_transactions return false unless restorable? @stack.each(&:restore!) true end
#rollback_transaction(transaction = nil)
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 610
def rollback_transaction(transaction = nil) @connection.lock.synchronize do transaction ||= @stack.last begin transaction.rollback ensure @stack.pop if @stack.last == transaction end transaction.rollback_records end end
#within_new_transaction(isolation: nil, joinable: true)
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 622
def within_new_transaction(isolation: nil, joinable: true) @connection.lock.synchronize do transaction = begin_transaction(isolation: isolation, joinable: joinable) begin yield transaction.user_transaction rescue Exception => error rollback_transaction after_failure_actions(transaction, error) raise ensure unless error if Thread.current.status == "aborting" rollback_transaction else begin commit_transaction rescue ActiveRecord::ConnectionFailed transaction.invalidate! unless transaction.state.completed? raise rescue Exception rollback_transaction(transaction) unless transaction.state.completed? raise end end end end ensure unless transaction&.state&.completed? @connection.throw_away! transaction&.incomplete! end end end