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

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

Instance Method Summary collapse

Instance Method Details

#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:



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/mongoid/clients/sessions.rb', line 83

def transaction(options = {}, session_options: {})
  with_session(session_options) do |session|
    begin
      session.start_transaction(options)
      yield
      commit_transaction(session)
    rescue Mongoid::Errors::Rollback
      abort_transaction(session)
    rescue Mongoid::Errors::InvalidSessionNesting
      # Session should be ended here.
      raise Mongoid::Errors::InvalidTransactionNesting.new
    rescue Mongo::Error::InvalidSession, Mongo::Error::InvalidTransactionOperation => e
      abort_transaction(session)
      raise Mongoid::Errors::TransactionError(e)
    rescue StandardError => e
      abort_transaction(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.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/mongoid/clients/sessions.rb', line 38

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
ensure
  Threaded.clear_session(client: persistence_context.client)
end