Skip to content

Commit

Permalink
Deadlocks inside transactions are functionally not retryable
Browse files Browse the repository at this point in the history
Even if we think the deadlocking query could be retried, the original
deadlock will have either broken or already rolled back our transaction.
  • Loading branch information
matthewd committed Mar 8, 2022
1 parent 82ee72c commit e02e06e
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -922,8 +922,13 @@ def retryable_connection_error?(exception)
end

def retryable_query_error?(exception)
exception.is_a?(Deadlocked) ||
exception.is_a?(LockWaitTimeout)
# We definitely can't retry if we were inside a transaction that was instantly
# rolled back by this error
if exception.is_a?(TransactionRollbackError) && savepoint_errors_invalidate_transactions? && open_transactions > 0
false
else
exception.is_a?(Deadlocked) || exception.is_a?(LockWaitTimeout)
end
end

def backoff(counter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -692,12 +692,10 @@ def translate_exception(exception, message:, sql:, binds:)
end

def retryable_query_error?(exception)
end

def retryable_connection_error?(exception)
case exception
when PG::ConnectionBad; !exception.message.end_with?("\n")
end
# We cannot retry anything if we're inside a broken transaction; we need to at
# least raise until the innermost savepoint is rolled back
@raw_connection&.transaction_status != ::PG::PQTRANS_INERROR &&
super
end

def get_oid_type(oid, fmod, column_name, sql_type = "")
Expand Down

0 comments on commit e02e06e

Please sign in to comment.