Module: Mongoid::Clients::Sessions::ClassMethods
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Extended In:
| |
Defined in: | lib/mongoid/clients/sessions.rb |
Constant Summary
-
CALLBACK_ACTIONS =
Internal use only
Actions that can be used to trigger transactional callbacks.
[:create, :destroy, :update]
Instance Attribute Summary
-
#in_transaction? ⇒ true | false
readonly
private
This method should be used to detect whether a persistence operation is executed inside transaction or not.
Instance Method Summary
-
#after_commit(*args, &block)
Sets up a callback is called after a commit of a transaction.
-
#after_create_commit(*args, &block)
Shortcut for after_commit
:hook
, on: :create. -
#after_destroy_commit(*args, &block)
Shortcut for after_commit
:hook
, on: :destroy. -
#after_rollback(*args, &block)
This callback is called after a create, update, or destroy are rolled back.
-
#after_save_commit(*args, &block)
Shortcut for after_commit
:hook
, on: [:create
,:update
]. -
#after_update_commit(*args, &block)
Shortcut for after_commit
:hook
, on: :update. -
#transaction(options = {}, session_options: {}) { ... }
Executes a block within the context of a transaction.
-
#with_session(options = {}) {|The| ... } ⇒ Object
Execute a block within the context of a session.
- #_session ⇒ Mongo::Session private
-
#assert_valid_transaction_action(actions)
private
Asserts that the given actions are valid for after_commit and after_rollback callbacks.
-
#run_abort_callbacks(session)
private
Runs after_rollback callbacks on modified documents.
-
#run_commit_callbacks(session)
private
Runs after_commit callbacks on modified documents.
-
#set_options_for_callbacks!(args)
private
Transforms custom options for after_commit and after_rollback callbacks into options for
set_callback
. - #transaction_include_any_action?(actions) ⇒ Boolean private
-
#transactions_not_supported_exceptions
private
Driver version 2.20 introduced a new exception for reporting that transactions are not supported.
Instance Attribute Details
#in_transaction? ⇒ true
| false
(readonly, private)
This method should be used to detect whether a persistence operation is executed inside transaction or not.
Currently this method is used to detect when #after_commit callbacks should be triggered. If we introduce implicit transactions and therefore do not need to handle two different ways of triggering callbacks, we may want to remove this method.
# File 'lib/mongoid/clients/sessions.rb', line 189
def in_transaction? _session&.in_transaction? || false end
Instance Method Details
#_session ⇒ Mongo::Session
(private)
# File 'lib/mongoid/clients/sessions.rb', line 175
def _session Threaded.get_session(client: persistence_context.client) end
#after_commit(*args, &block)
Sets up a callback is called after a commit of a transaction. The callback is called only if the document is created, updated, or destroyed in the transaction.
See ActiveSupport::Callbacks::ClassMethods::set_callback
for more information about method parameters and possible options.
# File 'lib/mongoid/clients/sessions.rb', line 119
def after_commit(*args, &block) (args) set_callback(:commit, :after, *args, &block) end
#after_create_commit(*args, &block)
Shortcut for after_commit :hook
, on: :create.
# File 'lib/mongoid/clients/sessions.rb', line 131
def after_create_commit(*args, &block) (args, on: :create) set_callback(:commit, :after, *args, &block) end
#after_destroy_commit(*args, &block)
Shortcut for after_commit :hook
, on: :destroy.
# File 'lib/mongoid/clients/sessions.rb', line 143
def after_destroy_commit(*args, &block) (args, on: :destroy) set_callback(:commit, :after, *args, &block) end
#after_rollback(*args, &block)
This callback is called after a create, update, or destroy are rolled back.
Please check the documentation of #after_commit for options.
# File 'lib/mongoid/clients/sessions.rb', line 151
def after_rollback(*args, &block) (args) set_callback(:rollback, :after, *args, &block) end
#after_save_commit(*args, &block)
Shortcut for after_commit :hook
, on: [ :create
, :update
]
# File 'lib/mongoid/clients/sessions.rb', line 125
def after_save_commit(*args, &block) (args, on: [ :create, :update ]) set_callback(:commit, :after, *args, &block) end
#after_update_commit(*args, &block)
Shortcut for after_commit :hook
, on: :update.
# File 'lib/mongoid/clients/sessions.rb', line 137
def after_update_commit(*args, &block) (args, on: :update) set_callback(:commit, :after, *args, &block) end
#assert_valid_transaction_action(actions) (private)
Asserts that the given actions are valid for after_commit and after_rollback callbacks.
# File 'lib/mongoid/clients/sessions.rb', line 234
def assert_valid_transaction_action(actions) if (actions - CALLBACK_ACTIONS).any? raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{CALLBACK_ACTIONS}" end end
#run_abort_callbacks(session) (private)
Runs after_rollback callbacks on modified documents.
# File 'lib/mongoid/clients/sessions.rb', line 207
def run_abort_callbacks(session) Threaded.clear_modified_documents(session).each do |doc| doc.run_after_callbacks(:rollback) end end
#run_commit_callbacks(session) (private)
Runs after_commit callbacks on modified documents.
# File 'lib/mongoid/clients/sessions.rb', line 197
def run_commit_callbacks(session) Threaded.clear_modified_documents(session).each do |doc| doc.run_after_callbacks(:commit) end end
#set_options_for_callbacks!(args) (private)
Transforms custom options for after_commit and after_rollback callbacks into options for set_callback
.
# File 'lib/mongoid/clients/sessions.rb', line 215
def (args) = args. args << if [:on] fire_on = Array( [:on]) assert_valid_transaction_action(fire_on) [:if] = [ -> { transaction_include_any_action?(fire_on) }, * [:if] ] end end
#transaction(options = {}, session_options: {}) { ... }
Executes a block within the context of a transaction.
If the block does not raise an error, the transaction is committed. If an error is raised, the transaction is aborted. The error is passed on except for the ::Mongoid::Errors::Rollback
. This error is not passed on, so you can raise is if you want to deliberately rollback the transaction.
# File 'lib/mongoid/clients/sessions.rb', line 89
def transaction( = {}, session_options: {}) with_session( ) do |session| begin session.with_transaction( ) do yield end run_commit_callbacks(session) rescue *transactions_not_supported_exceptions raise Mongoid::Errors::TransactionsNotSupported rescue Mongoid::Errors::Rollback run_abort_callbacks(session) rescue Mongoid::Errors::InvalidSessionNesting # Session should be ended here. raise Mongoid::Errors::InvalidTransactionNesting.new rescue Mongo::Error::InvalidSession, Mongo::Error::InvalidTransactionOperation => e run_abort_callbacks(session) raise Mongoid::Errors::TransactionError.new(e) rescue StandardError => e run_abort_callbacks(session) raise e end end end
#transaction_include_any_action?(actions) ⇒ Boolean (private)
# File 'lib/mongoid/clients/sessions.rb', line 240
def transaction_include_any_action?(actions) actions.any? do |action| case action when :create persisted? && previously_new_record? when :update !(previously_new_record? || destroyed?) when :destroy destroyed? end end end
#transactions_not_supported_exceptions (private)
Driver version 2.20 introduced a new exception for reporting that transactions are not supported. Prior to that, the condition was discovered by the rescue clause falling through to a different exception.
This method ensures that ::Mongoid
continues to work with older driver versions, by only returning the new exception.
Once support is removed for all versions prior to 2.20.0, we can replace this method.
# File 'lib/mongoid/clients/sessions.rb', line 168
def transactions_not_supported_exceptions return nil unless defined? Mongo::Error::TransactionsNotSupported Mongo::Error::TransactionsNotSupported end
#with_session(options = {}) {|The| ... } ⇒ Object
Execute a block within the context of a session.
# File 'lib/mongoid/clients/sessions.rb', line 42
def with_session( = {}) if Threaded.get_session(client: persistence_context.client) raise Mongoid::Errors::InvalidSessionNesting.new end session = persistence_context.client.start_session( ) Threaded.set_session(session, client: persistence_context.client) yield(session) rescue Mongo::Error::InvalidSession => ex if Mongo::Error::SessionsNotSupported === ex raise Mongoid::Errors::SessionsNotSupported.new else raise ex end rescue Mongo::Error::OperationFailure => ex if (ex.code == 40415 && ex. =~ /startTransaction/) || (ex.code == 20 && ex. =~ /Transaction/) raise Mongoid::Errors::TransactionsNotSupported.new else raise ex end rescue *transactions_not_supported_exceptions raise Mongoid::Errors::TransactionsNotSupported ensure Threaded.clear_session(client: persistence_context.client) end