diff options
| author | Jonathan Amsterdam <jba@google.com> | 2020-11-24 08:27:41 -0500 |
|---|---|---|
| committer | Jonathan Amsterdam <jba@google.com> | 2020-11-24 15:43:05 +0000 |
| commit | 0e5e58f29fe11134718d97859385e283577af225 (patch) | |
| tree | b67378a7b604609597653260f415fb32507babfb /internal/database/database.go | |
| parent | d3c0bf562280835347c4814ef272cec3f21552df (diff) | |
| download | go-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.go | 17 |
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") |
