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.
Change-Id: I2ca3252182115e78e00048aa229fd16dd427f61c
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/350111
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/database/database.go b/internal/database/database.go
index 227ff4c..ddfd074 100644
--- a/internal/database/database.go
+++ b/internal/database/database.go
@@ -230,6 +230,7 @@
// 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 @@
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 {