Method: Mongoid::Persistable#atomically

Defined in:
lib/mongoid/persistable.rb

#atomically(join_context: nil) ⇒ true | false

Execute operations atomically (in a single database call) for everything that would happen inside the block. This method supports nesting further calls to atomically, which will behave according to the options described below.

An option join_context can be given which, when true, will merge the operations declared by the given block with the atomically block wrapping the current invocation for the same document, if one exists. If this block or any other block sharing the same context raises before persisting, then all the operations of that context will not be persisted, and will also be reset in memory.

When join_context is false, the given block of operations will be persisted independently of other contexts. Failures in other contexts will not affect this one, so long as this block was able to run and persist changes.

The default value of join_context is set by the global configuration option join_contexts, whose own default is false.

Examples:

Execute the operations atomically.

document.atomically do
  document.set(name: "Tool").inc(likes: 10)
end

Execute some inner operations atomically, but independently from the outer operations.


document.atomically do
  document.inc likes: 10
  document.atomically join_context: false do
    # The following is persisted to the database independently.
    document.unset :origin
  end
  document.atomically join_context: true do
    # The following is persisted along with the other outer operations.
    document.inc member_count: 3
  end
  document.set name: "Tool"
end

Parameters:

  • join_context (true | false) (defaults to: nil)

    Join the context (i.e. merge declared atomic operations) of the atomically block wrapping this one for the same document, if one exists.

Returns:

  • (true | false)

    If the operation succeeded.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/mongoid/persistable.rb', line 94

def atomically(join_context: nil)
  join_context = Mongoid.join_contexts if join_context.nil?
  call_depth = @atomic_depth ||= 0
  has_own_context = call_depth.zero? || !join_context
  @atomic_updates_to_execute_stack ||= []
  _mongoid_push_atomic_context if has_own_context

  if block_given?
    @atomic_depth += 1
    yield(self)
    @atomic_depth -= 1
  end

  if has_own_context
    persist_atomic_operations @atomic_context
    _mongoid_remove_atomic_context_changes
  end

  true
rescue StandardError => e
  _mongoid_reset_atomic_context_changes! if has_own_context
  raise e
ensure
  _mongoid_pop_atomic_context if has_own_context

  if call_depth.zero?
    @atomic_depth = nil
    @atomic_updates_to_execute_stack = nil
  end
end