Module: ActiveRecord::Transactions
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
::ActiveSupport::Concern
|
|
Defined in: | activerecord/lib/active_record/transactions.rb |
Overview
See ClassMethods
for documentation.
Constant Summary
-
ACTIONS =
Internal use only
# File 'activerecord/lib/active_record/transactions.rb', line 8[:create, :destroy, :update]
Class Method Summary
::ActiveSupport::Concern
- Extended
class_methods | Define class methods from given block. |
included | Evaluate given block in context of base class, so that you can write class macros here. |
prepended | Evaluate given block in context of base class, so that you can write class macros here. |
append_features, prepend_features |
Instance Attribute Summary
- #_committed_already_called readonly private
- #_trigger_destroy_callback readonly private
- #_trigger_update_callback readonly private
- #has_transactional_callbacks? ⇒ Boolean readonly private
- #_new_record_before_last_commit rw Internal use only
- #trigger_transactional_callbacks? ⇒ Boolean readonly Internal use only
Instance Method Summary
-
#transaction(**options, &block)
See
ClassMethods
for detailed documentation. -
#with_transaction_returning_status
Executes a block within a transaction and captures its return value as a status flag.
-
#add_to_transaction(ensure_finalize = true)
private
Add the record to the current transaction so that the
#after_rollback
and#after_commit
callbacks can be called. -
#clear_transaction_record_state
private
Clear the new record state and id of a record.
- #init_internals private
-
#remember_transaction_record_state
private
Save the new record state and id of a record so it can be restored later if a transaction fails.
-
#restore_transaction_record_state(force_restore_state = false)
private
Restore the new record state and id of a record that was previously saved by a call to save_record_state.
-
#transaction_include_any_action?(actions) ⇒ Boolean
private
Determine if a transaction included an action for
:create
,:update
, or:destroy
. - #before_committed! Internal use only
-
#committed!(should_run_callbacks: true)
Internal use only
Call the
#after_commit
callbacks. - #destroy Internal use only
-
#rolledback!(force_restore_state: false, should_run_callbacks: true)
Internal use only
Call the
#after_rollback
callbacks. - #save Internal use only
- #save! Internal use only
- #touch Internal use only
DSL Calls
included
[ GitHub ]10 11 12 13 14
# File 'activerecord/lib/active_record/transactions.rb', line 10
included do define_callbacks :commit, :rollback, :before_commit, scope: [:kind, :name] end
Instance Attribute Details
#_committed_already_called (readonly, private)
[ GitHub ]# File 'activerecord/lib/active_record/transactions.rb', line 431
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
#_new_record_before_last_commit (rw)
# File 'activerecord/lib/active_record/transactions.rb', line 16
attr_accessor :_new_record_before_last_commit # :nodoc:
#_trigger_destroy_callback (readonly, private)
[ GitHub ]# File 'activerecord/lib/active_record/transactions.rb', line 431
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
#_trigger_update_callback (readonly, private)
[ GitHub ]# File 'activerecord/lib/active_record/transactions.rb', line 431
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
#has_transactional_callbacks? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activerecord/lib/active_record/transactions.rb', line 519
def has_transactional_callbacks? !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty? end
#trigger_transactional_callbacks? ⇒ Boolean
(readonly)
# File 'activerecord/lib/active_record/transactions.rb', line 425
def trigger_transactional_callbacks? # :nodoc: (@_new_record_before_last_commit || _trigger_update_callback) && persisted? || _trigger_destroy_callback && destroyed? end
Instance Method Details
#add_to_transaction(ensure_finalize = true) (private)
Add the record to the current transaction so that the #after_rollback
and #after_commit
callbacks can be called.
# File 'activerecord/lib/active_record/transactions.rb', line 513
def add_to_transaction(ensure_finalize = true) self.class.with_connection do |connection| connection.add_transaction_record(self, ensure_finalize) end end
#before_committed!
# File 'activerecord/lib/active_record/transactions.rb', line 373
def before_committed! # :nodoc: _run_before_commit_callbacks end
#clear_transaction_record_state (private)
Clear the new record state and id of a record.
# File 'activerecord/lib/active_record/transactions.rb', line 461
def clear_transaction_record_state return unless @_start_transaction_state @_start_transaction_state[:level] -= 1 @_start_transaction_state = nil if @_start_transaction_state[:level] < 1 end
#committed!(should_run_callbacks: true)
Call the #after_commit
callbacks.
Ensure that it is not called if the object was never persisted (failed create), but call it after the commit of a destroyed object.
# File 'activerecord/lib/active_record/transactions.rb', line 381
def committed!(should_run_callbacks: true) # :nodoc: @_start_transaction_state = nil if should_run_callbacks @_committed_already_called = true _run_commit_callbacks end ensure @_committed_already_called = @_trigger_update_callback = @_trigger_destroy_callback = false end
#destroy
# File 'activerecord/lib/active_record/transactions.rb', line 357
def destroy # :nodoc: with_transaction_returning_status { super } end
#init_internals (private)
[ GitHub ]# File 'activerecord/lib/active_record/transactions.rb', line 433
def init_internals super @_start_transaction_state = nil @_committed_already_called = nil @_new_record_before_last_commit = nil end
#remember_transaction_record_state (private)
Save the new record state and id of a record so it can be restored later if a transaction fails.
# File 'activerecord/lib/active_record/transactions.rb', line 441
def remember_transaction_record_state @_start_transaction_state ||= { id: id, new_record: @new_record, previously_new_record: @previously_new_record, destroyed: @destroyed, attributes: @attributes, frozen?: frozen?, level: 0 } @_start_transaction_state[:level] += 1 if _committed_already_called @_new_record_before_last_commit = false else @_new_record_before_last_commit = @_start_transaction_state[:new_record] end end
#restore_transaction_record_state(force_restore_state = false) (private)
Restore the new record state and id of a record that was previously saved by a call to save_record_state.
# File 'activerecord/lib/active_record/transactions.rb', line 468
def restore_transaction_record_state(force_restore_state = false) if restore_state = @_start_transaction_state if force_restore_state || restore_state[:level] <= 1 @new_record = restore_state[:new_record] @previously_new_record = restore_state[:previously_new_record] @destroyed = restore_state[:destroyed] @attributes = restore_state[:attributes].map do |attr| value = @attributes.fetch_value(attr.name) attr = attr.with_value_from_user(value) if attr.value != value attr end @mutations_from_database = nil @mutations_before_last_save = nil if self.class.composite_primary_key? if restore_state[:id] != @primary_key.map { |col| @attributes.fetch_value(col) } @primary_key.zip(restore_state[:id]).each do |col, val| @attributes.write_from_user(col, val) end end else if @attributes.fetch_value(@primary_key) != restore_state[:id] @attributes.write_from_user(@primary_key, restore_state[:id]) end end freeze if restore_state[:frozen?] end end end
#rolledback!(force_restore_state: false, should_run_callbacks: true)
Call the #after_rollback
callbacks. The force_restore_state
argument indicates if the record state should be rolled back to the beginning or just to the last savepoint.
# File 'activerecord/lib/active_record/transactions.rb', line 393
def rolledback!(force_restore_state: false, should_run_callbacks: true) # :nodoc: if should_run_callbacks _run_rollback_callbacks end ensure restore_transaction_record_state(force_restore_state) clear_transaction_record_state @_trigger_update_callback = @_trigger_destroy_callback = false if force_restore_state end
#save
# File 'activerecord/lib/active_record/transactions.rb', line 361
def save(**) # :nodoc: with_transaction_returning_status { super } end
#save!
# File 'activerecord/lib/active_record/transactions.rb', line 365
def save!(**) # :nodoc: with_transaction_returning_status { super } end
#touch
# File 'activerecord/lib/active_record/transactions.rb', line 369
def touch(*, **) # :nodoc: with_transaction_returning_status { super } end
#transaction(**options, &block)
See Transactions::ClassMethods
for detailed documentation.
# File 'activerecord/lib/active_record/transactions.rb', line 353
def transaction(**, &block) self.class.transaction(**, &block) end
#transaction_include_any_action?(actions) ⇒ Boolean
(private)
Determine if a transaction included an action for :create
, :update
, or :destroy
. Used in filtering callbacks.
# File 'activerecord/lib/active_record/transactions.rb', line 498
def transaction_include_any_action?(actions) actions.any? do |action| case action when :create persisted? && @_new_record_before_last_commit when :update !(@_new_record_before_last_commit || destroyed?) && _trigger_update_callback when :destroy _trigger_destroy_callback end end end
#with_transaction_returning_status
Executes a block within a transaction and captures its return value as a status flag. If the status is true, the transaction is committed, otherwise a ROLLBACK is issued. In any case, the status flag is returned.
This method is available within the context of an Base
instance.
# File 'activerecord/lib/active_record/transactions.rb', line 409
def with_transaction_returning_status self.class.with_connection do |connection| status = nil ensure_finalize = !connection.transaction_open? connection.transaction do add_to_transaction(ensure_finalize || has_transactional_callbacks?) remember_transaction_record_state status = yield raise ActiveRecord::Rollback unless status end status end end