module ActiveRecord::Transactions
def add_to_transaction
Add the record to the current transaction so that the +after_rollback+ and +after_commit+ callbacks
def add_to_transaction if self.class.connection.add_transaction_record(self) remember_transaction_record_state end end
def clear_transaction_record_state #:nodoc:
Clear the new record state and id of a record.
def clear_transaction_record_state #:nodoc: @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 @_start_transaction_state.clear if @_start_transaction_state[:level] < 1 end
def committed! #:nodoc:
but call it after the commit of a destroyed object.
Ensure that it is not called if the object was never persisted (failed create),
Call the +after_commit+ callbacks.
def committed! #:nodoc: run_callbacks :commit if destroyed? || persisted? ensure clear_transaction_record_state end
def destroy #:nodoc:
def destroy #:nodoc: with_transaction_returning_status { super } end
def remember_transaction_record_state #:nodoc:
Save the new record state and id of a record so it can be restored later if a transaction fails.
def remember_transaction_record_state #:nodoc: @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key) unless @_start_transaction_state.include?(:new_record) @_start_transaction_state[:new_record] = @new_record end unless @_start_transaction_state.include?(:destroyed) @_start_transaction_state[:destroyed] = @destroyed end @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1 @_start_transaction_state[:frozen?] = @attributes.frozen? end
def restore_transaction_record_state(force = false) #:nodoc:
Restore the new record state and id of a record that was previously saved by a call to save_record_state.
def restore_transaction_record_state(force = false) #:nodoc: unless @_start_transaction_state.empty? @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 if @_start_transaction_state[:level] < 1 || force restore_state = @_start_transaction_state was_frozen = restore_state[:frozen?] @attributes = @attributes.dup if @attributes.frozen? @new_record = restore_state[:new_record] @destroyed = restore_state[:destroyed] if restore_state.has_key?(:id) self.id = restore_state[:id] else @attributes.delete(self.class.primary_key) @attributes_cache.delete(self.class.primary_key) end @attributes.freeze if was_frozen @_start_transaction_state.clear end end end
def rollback_active_record_state!
def rollback_active_record_state! remember_transaction_record_state yield rescue Exception restore_transaction_record_state raise ensure clear_transaction_record_state end
def rolledback!(force_restore_state = false) #:nodoc:
state should be rolled back to the beginning or just to the last savepoint.
Call the +after_rollback+ callbacks. The +force_restore_state+ argument indicates if the record
def rolledback!(force_restore_state = false) #:nodoc: run_callbacks :rollback ensure restore_transaction_record_state(force_restore_state) end
def save(*) #:nodoc:
def save(*) #:nodoc: rollback_active_record_state! do with_transaction_returning_status { super } end end
def save!(*) #:nodoc:
def save!(*) #:nodoc: with_transaction_returning_status { super } end
def transaction(options = {}, &block)
def transaction(options = {}, &block) self.class.transaction(options, &block) end
def transaction_include_any_action?(actions) #:nodoc:
Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
def transaction_include_any_action?(actions) #:nodoc: actions.any? do |action| case action when :create transaction_record_state(:new_record) when :destroy destroyed? when :update !(transaction_record_state(:new_record) || destroyed?) end end end
def transaction_record_state(state) #:nodoc:
Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
def transaction_record_state(state) #:nodoc: @_start_transaction_state[state] end
def with_transaction_returning_status
This method is available within the context of an ActiveRecord::Base
a ROLLBACK is issued. In any case the status flag is returned.
status flag. If the status is true the transaction is committed, otherwise
Executes +method+ within a transaction and captures its return value as a
def with_transaction_returning_status status = nil self.class.transaction do add_to_transaction begin status = yield rescue ActiveRecord::Rollback @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 status = nil end raise ActiveRecord::Rollback unless status end status end