Class: ActiveRecord::ConnectionAdapters::Transaction

Inherits:
Object
  • Object
show all
Defined in:
activerecord/lib/active_record/connection_adapters/abstract/transaction.rb

Overview

:nodoc:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false) ⇒ Transaction

Returns a new instance of Transaction.


92
93
94
95
96
97
98
99
100
101
102
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 92

def initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false)
  @connection = connection
  @state = TransactionState.new
  @records = nil
  @isolation_level = isolation
  @materialized = false
  @joinable = joinable
  @run_commit_callbacks = run_commit_callbacks
  @lazy_enrollment_records = nil
  @dirty = false
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.


89
90
91
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 89

def connection
  @connection
end

#isolation_levelObject (readonly)

Returns the value of attribute isolation_level.


89
90
91
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 89

def isolation_level
  @isolation_level
end

#savepoint_nameObject (readonly)

Returns the value of attribute savepoint_name.


89
90
91
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 89

def savepoint_name
  @savepoint_name
end

#stateObject (readonly)

Returns the value of attribute state.


89
90
91
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 89

def state
  @state
end

#writtenObject

Returns the value of attribute written.


90
91
92
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 90

def written
  @written
end

#written_indirectlyObject

Returns the value of attribute written_indirectly.


90
91
92
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 90

def written_indirectly
  @written_indirectly
end

Instance Method Details

#add_record(record, ensure_finalize = true) ⇒ Object


112
113
114
115
116
117
118
119
120
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 112

def add_record(record, ensure_finalize = true)
  @records ||= []
  if ensure_finalize
    @records << record
  else
    @lazy_enrollment_records ||= ObjectSpace::WeakMap.new
    @lazy_enrollment_records[record] = record
  end
end

#before_commit_recordsObject


164
165
166
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 164

def before_commit_records
  records.uniq.each(&:before_committed!) if records && @run_commit_callbacks
end

#closed?Boolean

Returns:

  • (Boolean)

189
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 189

def closed?; false; end

#commit_recordsObject


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 168

def commit_records
  return unless records
  ite = records.uniq(&:__id__)
  already_run_callbacks = {}
  while record = ite.shift
    if @run_commit_callbacks
      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)
    end
  end
ensure
  ite&.each { |i| i.committed!(should_run_callbacks: false) }
end

#dirty!Object


104
105
106
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 104

def dirty!
  @dirty = true
end

#dirty?Boolean

Returns:

  • (Boolean)

108
109
110
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 108

def dirty?
  @dirty
end

#full_rollback?Boolean

Returns:

  • (Boolean)

187
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 187

def full_rollback?; true; end

#joinable?Boolean

Returns:

  • (Boolean)

188
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 188

def joinable?; @joinable; end

#materialize!Object


136
137
138
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 136

def materialize!
  @materialized = true
end

#materialized?Boolean

Returns:

  • (Boolean)

140
141
142
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 140

def materialized?
  @materialized
end

#open?Boolean

Returns:

  • (Boolean)

190
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 190

def open?; !closed?; end

#recordsObject


122
123
124
125
126
127
128
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 122

def records
  if @lazy_enrollment_records
    @records.concat @lazy_enrollment_records.values
    @lazy_enrollment_records = nil
  end
  @records
end

#restartable?Boolean

Can this transaction's current state be recreated by rollback+begin ?

Returns:

  • (Boolean)

132
133
134
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 132

def restartable?
  joinable? && !dirty?
end

#restore!Object


144
145
146
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 144

def restore!
  @materialized = false
end

#rollback_recordsObject


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 148

def rollback_records
  return unless records
  ite = records.uniq(&:__id__)
  already_run_callbacks = {}
  while record = ite.shift
    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|
    i.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: false)
  end
end