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
# File 'lib/mongoid/clients/sessions.rb', line 17
Actions that can be used to trigger transactional callbacks.
%i[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, enforced_options = {})
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 178
def in_transaction? _session&.in_transaction? || false end
Instance Method Details
#_session ⇒ Mongo::Session (private)
# File 'lib/mongoid/clients/sessions.rb', line 164
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 108
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 120
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 132
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 140
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 114
def after_save_commit(*args, &block) (args, on: %i[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 126
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 223
def assert_valid_transaction_action(actions) return unless (actions - CALLBACK_ACTIONS).any? raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{CALLBACK_ACTIONS}" end
#run_abort_callbacks(session) (private)
Runs after_rollback callbacks on modified documents.
# File 'lib/mongoid/clients/sessions.rb', line 196
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 186
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, enforced_options = {}) (private)
Transforms custom options for after_commit and after_rollback callbacks into options for set_callback.
# File 'lib/mongoid/clients/sessions.rb', line 204
def (args, = {}) = args..merge() args << return unless [:on] fire_on = Array([:on]) assert_valid_transaction_action(fire_on) [:if] = [ -> { transaction_include_any_action?(fire_on) }, *[:if] ] 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 83
def transaction( = {}, session_options: {}, &block) with_session() do |session| session.with_transaction(, &block).tap { 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
#transaction_include_any_action?(actions) ⇒ Boolean (private)
# File 'lib/mongoid/clients/sessions.rb', line 230
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 157
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 38
def with_session( = {}) raise Mongoid::Errors::InvalidSessionNesting.new if Threaded.get_session(client: persistence_context.client) session = persistence_context.client.start_session() Threaded.set_session(session, client: persistence_context.client) yield(session) rescue Mongo::Error::InvalidSession => e raise Mongoid::Errors::SessionsNotSupported.new if e.is_a?(Mongo::Error::SessionsNotSupported) raise e rescue Mongo::Error::OperationFailure => e if (e.code == 40_415 && e. =~ /startTransaction/) || (e.code == 20 && e. =~ /Transaction/) raise Mongoid::Errors::TransactionsNotSupported.new else raise e end rescue *transactions_not_supported_exceptions raise Mongoid::Errors::TransactionsNotSupported ensure Threaded.clear_modified_documents(session) Threaded.clear_session(client: persistence_context.client) end