aboutsummaryrefslogtreecommitdiff
path: root/internal/database/database.go
diff options
context:
space:
mode:
authorJonathan Amsterdam <jba@google.com>2020-11-24 08:27:41 -0500
committerJonathan Amsterdam <jba@google.com>2020-11-24 15:43:05 +0000
commit0e5e58f29fe11134718d97859385e283577af225 (patch)
treeb67378a7b604609597653260f415fb32507babfb /internal/database/database.go
parentd3c0bf562280835347c4814ef272cec3f21552df (diff)
downloadgo-x-pkgsite-0e5e58f29fe11134718d97859385e283577af225.tar.xz
internal/database: support pgx driver
Test with both the postgres and pgx drivers. Recognize the pgx error type as well as the pq error type. Change-Id: If290e3e16013fd40ce2899b1cbae9fc0c9416ebd Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/272786 Trust: Jonathan Amsterdam <jba@google.com> Run-TryBot: Jonathan Amsterdam <jba@google.com> TryBot-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: Julie Qiu <julie@golang.org>
Diffstat (limited to 'internal/database/database.go')
-rw-r--r--internal/database/database.go17
1 files changed, 15 insertions, 2 deletions
diff --git a/internal/database/database.go b/internal/database/database.go
index 1ffc12ba..be025553 100644
--- a/internal/database/database.go
+++ b/internal/database/database.go
@@ -17,6 +17,7 @@ import (
"sync"
"time"
+ "github.com/jackc/pgconn"
"github.com/lib/pq"
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/log"
@@ -186,8 +187,7 @@ func (db *DB) transactWithRetry(ctx context.Context, opts *sql.TxOptions, txFunc
const maxRetries = 30
for i := 0; i <= maxRetries; i++ {
err = db.transact(ctx, opts, txFunc)
- var perr *pq.Error
- if errors.As(err, &perr) && perr.Code == serializationFailureCode {
+ if isSerializationFailure(err) {
db.mu.Lock()
if i > db.maxRetries {
db.maxRetries = i
@@ -203,6 +203,19 @@ func (db *DB) transactWithRetry(ctx context.Context, opts *sql.TxOptions, txFunc
return fmt.Errorf("reached max number of tries due to serialization failure (%d)", maxRetries)
}
+func isSerializationFailure(err error) bool {
+ // The underlying error type depends on the driver. Try both pq and pgx types.
+ var perr *pq.Error
+ if errors.As(err, &perr) && perr.Code == serializationFailureCode {
+ return true
+ }
+ var gerr *pgconn.PgError
+ if errors.As(err, &gerr) && gerr.Code == serializationFailureCode {
+ return true
+ }
+ return false
+}
+
func (db *DB) transact(ctx context.Context, opts *sql.TxOptions, txFunc func(*DB) error) (err error) {
if db.InTransaction() {
return errors.New("a DB Transact function was called on a DB already in a transaction")