class ActiveRecord::ConnectionAdapters::TransactionManager

:nodoc:

def after_failure_actions(transaction, error)

Deallocate invalidated prepared statements outside of the transaction
def after_failure_actions(transaction, error)
  return unless transaction.is_a?(RealTransaction)
  return unless error.is_a?(ActiveRecord::PreparedStatementCacheExpired)
  @connection.clear_cache!
end

def begin_transaction(isolation: nil, joinable: true, _lazy: true)

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

def commit_transaction

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

def current_transaction

def current_transaction
  @stack.last || NULL_TRANSACTION
end

def dirty_current_transaction

def dirty_current_transaction
  current_transaction.dirty!
end

def disable_lazy_transactions!

def disable_lazy_transactions!
  materialize_transactions
  @lazy_transactions_enabled = false
end

def enable_lazy_transactions!

def enable_lazy_transactions!
  @lazy_transactions_enabled = true
end

def initialize(connection)

:nodoc:
def initialize(connection)
  @stack = []
  @connection = connection
  @has_unmaterialized_transactions = false
  @materializing_transactions = false
  @lazy_transactions_enabled = true
end

def lazy_transactions_enabled?

def lazy_transactions_enabled?
  @lazy_transactions_enabled
end

def materialize_transactions

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

def open_transactions

def open_transactions
  @stack.size
end

def restorable?

def restorable?
  @stack.none?(&:dirty?)
end

def restore_transactions

def restore_transactions
  return false unless restorable?
  @stack.each(&:restore!)
  true
end

def rollback_transaction(transaction = nil)

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

def within_new_transaction(isolation: nil, joinable: true)

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