Follow up - 2c8825b387
- ActiveJobLock lock update fails due to ActiveRecord::Deadlocked "Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction" exception.
This commit is contained in:
parent
4e8cf209ca
commit
47778f2d2f
2 changed files with 25 additions and 0 deletions
|
@ -95,6 +95,10 @@ module HasActiveJobLock
|
||||||
# but it's safe to retry as described in the docs:
|
# but it's safe to retry as described in the docs:
|
||||||
# https://www.postgresql.org/docs/10/transaction-iso.html
|
# https://www.postgresql.org/docs/10/transaction-iso.html
|
||||||
e.message.include?('PG::TRSerializationFailure') ? retry : raise
|
e.message.include?('PG::TRSerializationFailure') ? retry : raise
|
||||||
|
rescue ActiveRecord::Deadlocked => e
|
||||||
|
# MySQL handles lock race condition differently and raises a Deadlock exception:
|
||||||
|
# Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
e.message.include?('Mysql2::Error: Deadlock found when trying to get lock') ? retry : raise
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue ActiveRecord::RecordNotUnique
|
||||||
existing_active_job_lock!
|
existing_active_job_lock!
|
||||||
end
|
end
|
||||||
|
|
|
@ -121,6 +121,27 @@ RSpec.describe HasActiveJobLock, type: :job do
|
||||||
expect(exception_raised).to be true
|
expect(exception_raised).to be true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when ActiveRecord::Deadlocked 'Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction' is raised" do
|
||||||
|
|
||||||
|
it 'retries execution until succeed' do
|
||||||
|
allow(ActiveRecord::Base.connection).to receive(:open_transactions).and_return(0)
|
||||||
|
allow(ActiveJobLock).to receive(:transaction).and_call_original
|
||||||
|
exception_raised = false
|
||||||
|
allow(ActiveJobLock).to receive(:transaction).with(isolation: :serializable) do |&block|
|
||||||
|
|
||||||
|
if !exception_raised
|
||||||
|
exception_raised = true
|
||||||
|
raise ActiveRecord::Deadlocked, 'Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction'
|
||||||
|
end
|
||||||
|
|
||||||
|
block.call
|
||||||
|
end
|
||||||
|
|
||||||
|
expect { job_class.perform_later }.to have_enqueued_job(job_class).exactly(:once)
|
||||||
|
expect(exception_raised).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
include_examples 'handle locking of jobs'
|
include_examples 'handle locking of jobs'
|
||||||
|
|
Loading…
Reference in a new issue