Module: DeadlockRetry::ClassMethods

Defined in:
lib/deadlock_retry.rb

Constant Summary collapse

DEADLOCK_ERROR_MESSAGES =
[
  "Deadlock found when trying to get lock",
  "Lock wait timeout exceeded",
  "deadlock detected"
]
MAXIMUM_RETRIES_ON_DEADLOCK =
10

Instance Method Summary collapse

Instance Method Details

#transaction_with_deadlock_handling(*objects, &block) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/deadlock_retry.rb', line 25

def transaction_with_deadlock_handling(*objects, &block)
  retry_count = 0

  check_innodb_status_available

  begin
    transaction_without_deadlock_handling(*objects, &block)
  rescue ActiveRecord::StatementInvalid => error
    raise if in_nested_transaction?
    if DEADLOCK_ERROR_MESSAGES.any? { |msg| error.message =~ /#{Regexp.escape(msg)}/ }
      raise if retry_count >= MAXIMUM_RETRIES_ON_DEADLOCK
      retry_count += 1
      logger.info "Deadlock detected on retry #{retry_count}, restarting transaction"
      log_innodb_status if DeadlockRetry.innodb_status_cmd
      exponential_pause(retry_count)
      retry
    else
      raise
    end
  end
end