Forbid Sidekiq scheduling in transactions

Scheduling jobs in transactions can lead to race conditions where a job
runs before a transaction has been committed. The added initializer
ensures the various Sidekiq scheduling methods raise an error when
called inside a transaction.

Fixes #27233
This commit is contained in:
Yorick Peterse 2017-02-20 14:28:05 +01:00 committed by Douwe Maan
parent 51c196160a
commit 4edb505bb6

View file

@ -0,0 +1,27 @@
module Sidekiq
module Worker
module ClassMethods
module NoSchedulingFromTransactions
NESTING = ::Rails.env.test? ? 1 : 0
%i(perform_async perform_at perform_in).each do |name|
define_method(name) do |*args|
if ActiveRecord::Base.connection.open_transactions > NESTING
raise <<-MSG.strip_heredoc
`#{self}.#{name}` cannot be called inside a transaction as this can lead to race
conditions when the worker runs before the transaction is committed and tries to
access a model that has not been saved yet.
Schedule the worker from inside a `run_after_commit` block instead.
MSG
end
super(*args)
end
end
end
prepend NoSchedulingFromTransactions
end
end
end