module Granite::Action::TransactionManager

Constants

TRANSACTIONS_STACK_KEY

Public Class Methods

after_commit(listener = nil, &block) click to toggle source

Adds a block or listener object to be executed after finishing the current transaction. Callbacks are reset after each transaction. @param [Object] listener an object which will receive `run_callbacks(:commit)` after transaction committed @param [Proc] block a block which will be called after transaction committed

# File lib/granite/action/transaction_manager.rb, line 23
def after_commit(listener = nil, &block)
  callback = listener || block

  fail 'Block or object is required to register after_commit hook!' unless callback

  transactions_stack.add_callback callback
end
transaction(&block) click to toggle source

Runs a block in a transaction It will open a new transaction or append a block to the current one if it exists @return [Object] result of a block

# File lib/granite/action/transaction_manager.rb, line 13
def transaction(&block)
  run_in_transaction(&block) || false
ensure
  finish_root_transaction if transactions_stack.depth.zero?
end

Private Class Methods

finish_root_transaction() click to toggle source
# File lib/granite/action/transaction_manager.rb, line 53
def finish_root_transaction
  callbacks = transactions_stack.callbacks

  self.transactions_stack = nil

  trigger_after_commit_callbacks(callbacks)
end
log_errors(errors) click to toggle source
# File lib/granite/action/transaction_manager.rb, line 78
def log_errors(errors)
  errors.each do |error|
    ActiveData.config.logger.error "Unhandled error in callback: #{error.inspect}\n#{error.backtrace.join("\n")}"
  end
end
run_in_transaction(&block) click to toggle source
# File lib/granite/action/transaction_manager.rb, line 43
def run_in_transaction(&block)
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.transaction(requires_new: true) do
      transactions_stack.transaction(&block)
    end
  else
    transactions_stack.transaction(&block)
  end
end
transactions_stack() click to toggle source
# File lib/granite/action/transaction_manager.rb, line 35
def transactions_stack
  Thread.current[TRANSACTIONS_STACK_KEY] ||= TransactionsStack.new
end
transactions_stack=(value) click to toggle source
# File lib/granite/action/transaction_manager.rb, line 39
def transactions_stack=(value)
  Thread.current[TRANSACTIONS_STACK_KEY] = value
end
trigger_after_commit_callbacks(callbacks) click to toggle source
# File lib/granite/action/transaction_manager.rb, line 61
def trigger_after_commit_callbacks(callbacks)
  collected_errors = []

  callbacks.reverse_each do |callback|
    begin
      callback.respond_to?(:run_callbacks) ? callback.run_callbacks(:commit) : callback.call
    rescue StandardError => e
      collected_errors << e
    end
  end

  return unless collected_errors.any?

  log_errors(collected_errors[1..-1])
  fail collected_errors.first
end