mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-01 10:11:11 +02:00
sqldb: improve serialization error handling
This commit is contained in:
@@ -22,7 +22,7 @@ const (
|
||||
// DefaultNumTxRetries is the default number of times we'll retry a
|
||||
// transaction if it fails with an error that permits transaction
|
||||
// repetition.
|
||||
DefaultNumTxRetries = 10
|
||||
DefaultNumTxRetries = 20
|
||||
|
||||
// DefaultRetryDelay is the default delay between retries. This will be
|
||||
// used to generate a random delay between 0 and this value.
|
||||
|
@@ -17,6 +17,16 @@ var (
|
||||
// ErrRetriesExceeded is returned when a transaction is retried more
|
||||
// than the max allowed valued without a success.
|
||||
ErrRetriesExceeded = errors.New("db tx retries exceeded")
|
||||
|
||||
// postgresErrMsgs are strings that signify retriable errors resulting
|
||||
// from serialization failures.
|
||||
postgresErrMsgs = []string{
|
||||
"could not serialize access",
|
||||
"current transaction is aborted",
|
||||
"not enough elements in RWConflictPool",
|
||||
"deadlock detected",
|
||||
"commit unexpectedly resulted in rollback",
|
||||
}
|
||||
)
|
||||
|
||||
// MapSQLError attempts to interpret a given error as a database agnostic SQL
|
||||
@@ -41,10 +51,11 @@ func MapSQLError(err error) error {
|
||||
// Sometimes the error won't be properly wrapped, so we'll need to
|
||||
// inspect raw error itself to detect something we can wrap properly.
|
||||
// This handles a postgres variant of the error.
|
||||
const postgresErrMsg = "could not serialize access"
|
||||
if strings.Contains(err.Error(), postgresErrMsg) {
|
||||
return &ErrSerializationError{
|
||||
DBError: err,
|
||||
for _, postgresErrMsg := range postgresErrMsgs {
|
||||
if strings.Contains(err.Error(), postgresErrMsg) {
|
||||
return &ErrSerializationError{
|
||||
DBError: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +116,20 @@ func parsePostgresError(pqErr *pgconn.PgError) error {
|
||||
DBError: pqErr,
|
||||
}
|
||||
|
||||
// In failed SQL transaction because we didn't catch a previous
|
||||
// serialization error, so return this one as a serialization error.
|
||||
case pgerrcode.InFailedSQLTransaction:
|
||||
return &ErrSerializationError{
|
||||
DBError: pqErr,
|
||||
}
|
||||
|
||||
// Deadlock detedted because of a serialization error, so return this
|
||||
// one as a serialization error.
|
||||
case pgerrcode.DeadlockDetected:
|
||||
return &ErrSerializationError{
|
||||
DBError: pqErr,
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown postgres error: %w", pqErr)
|
||||
}
|
||||
|
Reference in New Issue
Block a user