Skip to content

Instantly share code, notes, and snippets.

@urbanczykd
Created August 13, 2015 14:50
Show Gist options
  • Save urbanczykd/10f1c562dec36870a1fb to your computer and use it in GitHub Desktop.
Save urbanczykd/10f1c562dec36870a1fb to your computer and use it in GitHub Desktop.
class DeadlockRetry
DEADLOCK_ERROR_MESSAGES = ["Deadlock found when trying to get lock", "Lock wait timeout exceeded"]
MAXIMUM_RETRIES_ON_DEADLOCK = 10
class << self
def deadlock_free(object, &block)
retry_count = 0
begin
object.class.name.constantize.transaction do
# raise ActiveRecord::StatementInvalid.new("Deadlock found when trying to get lock")
object.lock!
block.call
end
rescue ActiveRecord::StatementInvalid => error
if DEADLOCK_ERROR_MESSAGES.any? { |msg| error.message =~ /#{::Regexp.escape(msg)}/ }
raise if retry_count >= MAXIMUM_RETRIES_ON_DEADLOCK
# maybe some sleep in here ?
retry_count += 1
puts "Deadlock detected on retry #{retry_count}, restarting transaction"
retry
else
raise
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment