retry on serialization errors

This commit is contained in:
Alex Suraci 2018-11-15 13:17:42 -05:00
parent efb15205e9
commit 7e96021428

View file

@ -6,10 +6,10 @@ import (
"regexp" "regexp"
"time" "time"
"github.com/lib/pq"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
// import third party drivers // import third party drivers
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
) )
@ -51,19 +51,34 @@ var (
// NOTE(ericchiang): For some reason using `SET SESSION CHARACTERISTICS AS TRANSACTION` at a // NOTE(ericchiang): For some reason using `SET SESSION CHARACTERISTICS AS TRANSACTION` at a
// session level didn't work for some edge cases. Might be something worth exploring. // session level didn't work for some edge cases. Might be something worth exploring.
executeTx: func(db *sql.DB, fn func(sqlTx *sql.Tx) error) error { executeTx: func(db *sql.DB, fn func(sqlTx *sql.Tx) error) error {
for {
tx, err := db.Begin() tx, err := db.Begin()
if err != nil { if err != nil {
return err return err
} }
defer tx.Rollback() defer tx.Rollback()
if _, err := tx.Exec(`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;`); err != nil { if _, err := tx.Exec(`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;`); err != nil {
return err return err
} }
if err := fn(tx); err != nil { if err := fn(tx); err != nil {
return err return err
} }
return tx.Commit()
err = tx.Commit()
if err != nil {
if pqErr, ok := err.(*pq.Error); ok && pqErr.Code == "40001" {
// serialization error; retry
continue
}
return err
}
return nil
}
}, },
supportsTimezones: true, supportsTimezones: true,