Module: Mongoid::Clients::Sessions::ClassMethods

Included in:
Mongoid
Defined in:
lib/mongoid/clients/sessions.rb

Constant Summary collapse

CALLBACK_ACTIONS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Actions that can be used to trigger transactional callbacks.

[:create, :destroy, :update]

Instance Method Summary collapse

Instance Method Details

#after_commit(*args, &block) ⇒ Object

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.



119
120
121
122
# File 'lib/mongoid/clients/sessions.rb', line 119

def after_commit(*args, &block)
  set_options_for_callbacks!(args)
  set_callback(:commit, :after, *args, &block)
end

#after_create_commit(*args, &block) ⇒ Object

Shortcut for after_commit :hook, on: :create.



131
132
133
134
# File 'lib/mongoid/clients/sessions.rb', line 131

def after_create_commit(*args, &block)
  set_options_for_callbacks!(args, on: :create)
  set_callback(:commit, :after, *args, &block)
end

#after_destroy_commit(*args, &block) ⇒ Object

Shortcut for after_commit :hook, on: :destroy.



143
144
145
146
# File 'lib/mongoid/clients/sessions.rb', line 143

def after_destroy_commit(*args, &block)
  set_options_for_callbacks!(args, on: :destroy)
  set_callback(:commit, :after, *args, &block)
end

#after_rollback(*args, &block) ⇒ Object

This callback is called after a create, update, or destroy are rolled back.

Please check the documentation of after_commit for options.



151
152
153
154
# File 'lib/mongoid/clients/sessions.rb', line 151

def after_rollback(*args, &block)
  set_options_for_callbacks!(args)
  set_callback(:rollback, :after, *args, &block)
end

#after_save_commit(*args, &block) ⇒ Object

Shortcut for after_commit :hook, on: [ :create, :update ]



125
126
127
128
# File 'lib/mongoid/clients/sessions.rb', line 125

def after_save_commit(*args, &block)
  set_options_for_callbacks!(args, on: [ :create, :update ])
  set_callback(:commit, :after, *args, &block)
end

#after_update_commit(*args, &block) ⇒ Object

Shortcut for after_commit :hook, on: :update.



137
138
139
140
# File 'lib/mongoid/clients/sessions.rb', line 137

def after_update_commit(*args, &block)
  set_options_for_callbacks!(args, on: :update)
  set_callback(:commit, :after, *args, &block)
end

#transaction(options = {}, session_options: {}) { ... } ⇒ Object

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.

Parameters:

  • options (Hash) (defaults to: {})

    The transaction options. Please see the driver documentation for the available session options.

  • session_options (Hash) (defaults to: {})

    The session options. A MongoDB transaction must be started inside a session, therefore a session will be started. Please see the driver documentation for the available session options.

Yields:

  • Provided block will be executed inside a transaction.

Raises:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/mongoid/clients/sessions.rb', line 89

def transaction(options = {}, session_options: {})
  with_session(session_options) do |session|
    begin
      session.with_transaction(options) 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

#with_session(options = {}) {|The| ... } ⇒ Object

Execute a block within the context of a session.

Examples:

Execute some operations in the context of a session.

Band.with_session(causal_consistency: true) do
  band = Band.create
  band.records << Record.new
  band.save
  band.reload.records
end

Parameters:

  • options (Hash) (defaults to: {})

    The session options. Please see the driver documentation for the available session options.

Yield Parameters:

  • The (Mongo::Session)

    session being used for the block.

Returns:

  • (Object)

    The result of calling the block.

Raises:

  • (Errors::InvalidSessionUse)

    If an operation is attempted on a model using another client from which the session was started or if sessions are nested.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/mongoid/clients/sessions.rb', line 42

def with_session(options = {})
  if Threaded.get_session(client: persistence_context.client)
    raise Mongoid::Errors::InvalidSessionNesting.new
  end
  session = persistence_context.client.start_session(options)
  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.server_message =~ /startTransaction/) ||
     (ex.code == 20 && ex.server_message =~ /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