Module: Activerecord::Transactionable::ClassMethods

Defined in:
lib/activerecord/transactionable.rb

Instance Method Summary collapse

Instance Method Details

#transaction_wrapper(object: nil, **args) ⇒ Object

Raises:

  • (ArgumentError)


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/activerecord/transactionable.rb', line 56

def transaction_wrapper(object: nil, **args)
  lock = args.delete(:lock)
  inside_args = extract_args(args, INSIDE_TRANSACTION_ERROR_HANDLERS)
  outside_args = extract_args(args, OUTSIDE_TRANSACTION_ERROR_HANDLERS)
  transaction_open = ActiveRecord::Base.connection.transaction_open?
  raise ArgumentError, "#{self} does not know how to handle arguments: #{args.keys.inspect}" unless args.keys.empty?
  if ERRORS_TO_DISALLOW_INSIDE_TRANSACTION.detect { |error| inside_args.values.flatten.uniq.include?(error) }
    raise ArgumentError, "#{self} should not rescue #{ERRORS_TO_DISALLOW_INSIDE_TRANSACTION.inspect} inside a transaction: #{inside_args.keys.inspect}"
  end
  transaction_args = extract_args(args, TRANSACTION_METHOD_ARG_NAMES)
  if transaction_open
    unless transaction_args[REQUIRES_NEW]
      transaction_args[REQUIRES_NEW] = true
      logger.warn("[#{self}.transaction_wrapper] Opening a nested transaction. Setting require_new: true")
    else
      logger.debug("[#{self}.transaction_wrapper] Will start a nested transaction.")
    end
    run_inside_transaction_block(transaction_args: transaction_args, inside_args: inside_args, lock: lock, transaction_open: transaction_open, object: object) do
      yield
    end
  else
    error_handler_outside_transaction(object: object, transaction_open: transaction_open, **outside_args) do
      run_inside_transaction_block(transaction_args: transaction_args, inside_args: inside_args, lock: lock, transaction_open: transaction_open, object: object) do
        yield
      end
    end
  end
end