class Mongoid::Orderable::Handlers::Transaction

Executes a block within the context of a MongoDB transaction.

Constants

RETRY_SLEEP
THREAD_KEY

Attributes

doc[R]

Public Class Methods

new(doc) click to toggle source
# File lib/mongoid/orderable/handlers/transaction.rb, line 13
def initialize(doc)
  @doc = doc
end

Public Instance Methods

with_transaction() { || ... } click to toggle source
# File lib/mongoid/orderable/handlers/transaction.rb, line 17
def with_transaction(&block)
  Mongoid::QueryCache.uncached do
    if Thread.current[THREAD_KEY]
      yield
    else
      Thread.current[THREAD_KEY] = true
      retries = transaction_max_retries
      begin
        do_transaction(&block)
      rescue Mongo::Error::OperationFailure => e
        sleep(RETRY_SLEEP)
        retries -= 1
        retry if retries >= 0
        raise Mongoid::Orderable::Errors::TransactionFailed.new(e)
      ensure
        Thread.current[THREAD_KEY] = nil
      end
    end
  end
end

Protected Instance Methods

do_transaction() { || ... } click to toggle source
# File lib/mongoid/orderable/handlers/transaction.rb, line 40
def do_transaction(&_block)
  doc.class.with_session(session_opts) do |session|
    doc.class.with(persistence_opts) do
      session.start_transaction(transaction_opts)
      yield
      session.commit_transaction
    end
  end
end
persistence_opts() click to toggle source
# File lib/mongoid/orderable/handlers/transaction.rb, line 55
def persistence_opts
  { read: { mode: :primary } }
end
session_opts() click to toggle source
# File lib/mongoid/orderable/handlers/transaction.rb, line 50
def session_opts
  { read: { mode: :primary },
    causal_consistency: true }
end
transaction_max_retries() click to toggle source
# File lib/mongoid/orderable/handlers/transaction.rb, line 65
def transaction_max_retries
  doc.orderable_keys.map {|k| doc.class.orderable_configs.dig(k, :transaction_max_retries) }.compact.max
end
transaction_opts() click to toggle source
# File lib/mongoid/orderable/handlers/transaction.rb, line 59
def transaction_opts
  { read: { mode: :primary },
    read_concern: { level: 'majority' },
    write_concern: { w: 'majority' } }
end