internal/database: back off serialization failure exponentially
When a transaction encounters a serialization failure, retry after
waiting some time, instead of retrying immediately. Double the wait
time on each failure.
Trust: Jonathan Amsterdam
Run-TryBot: Jonathan Amsterdam
@@ -230,6 +230,7 @@ func (db *DB) transactWithRetry(ctx context.Context, opts *sql.TxOptions, txFunc
// Retry on serialization failure, up to some max.
// See https://www.postgresql.org/docs/11/transaction-iso.html.
const maxRetries = 10
+ sleepDur := 125 * time.Millisecond
for i := 0; i <= maxRetries; i++ {
err = db.transact(ctx, opts, txFunc)
if isSerializationFailure(err) {
@@ -238,7 +239,9 @@ func (db *DB) transactWithRetry(ctx context.Context, opts *sql.TxOptions, txFunc
db.maxRetries = i
}
db.mu.Unlock()
- log.Debugf(ctx, "serialization failure; retrying")
+ log.Debugf(ctx, "serialization failure; retrying after %s", sleepDur)
+ time.Sleep(sleepDur)
+ sleepDur *= 2
continue
}
if err != nil {
