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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/activerecord/transactionable.rb', line 58
def transaction_wrapper(object: nil, **args)
lock = args.delete(:lock)
inside_args = (args, INSIDE_TRANSACTION_ERROR_HANDLERS)
outside_args = (args, OUTSIDE_TRANSACTION_ERROR_HANDLERS)
transaction_args = (args, TRANSACTION_METHOD_ARG_NAMES)
transaction_open = ActiveRecord::Base.connection.transaction_open?
unless args.keys.empty?
raise ArgumentError,
"#{self} does not know how to handle arguments: #{args.keys.inspect}"
end
if ERRORS_TO_DISALLOW_INSIDE_TRANSACTION.detect do |error|
inside_args.values.flatten.uniq.include?(error)
end
raise ArgumentError,
"#{self} should not rescue #{ERRORS_TO_DISALLOW_INSIDE_TRANSACTION.inspect} inside a transaction: #{inside_args.keys.inspect}"
end
if transaction_open
if transaction_args[REQUIRES_NEW]
logger.debug("[#{self}.transaction_wrapper] Will start a nested transaction.")
else
transaction_args[REQUIRES_NEW] = true
logger.warn("[#{self}.transaction_wrapper] Opening a nested transaction. Setting #{REQUIRES_NEW}: true")
end
end
error_handler_outside_transaction(
object: object,
transaction_open: transaction_open,
**outside_args,
) do |outside_is_retry|
run_inside_transaction_block(
transaction_args: transaction_args,
inside_args: inside_args,
lock: lock,
transaction_open: transaction_open,
object: object,
) do |is_retry|
yield outside_is_retry || is_retry
end
end
end
|