Retry aborted transactions on Spanner. (#103289)
* Retry aborted transactions on Spanner.
This commit is contained in:
@@ -8,10 +8,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
spannerclient "cloud.google.com/go/spanner"
|
||||
_ "github.com/googleapis/go-sql-spanner"
|
||||
spannerdriver "github.com/googleapis/go-sql-spanner"
|
||||
"google.golang.org/api/option"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"xorm.io/core"
|
||||
)
|
||||
@@ -425,3 +427,7 @@ func SpannerConnectorConfigToClientOptions(connectorConfig spannerdriver.Connect
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func (s *spanner) RetryOnError(err error) bool {
|
||||
return err != nil && spannerclient.ErrCode(spannerclient.ToSpannerError(err)) == codes.Aborted
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
sqlite "github.com/mattn/go-sqlite3"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
@@ -474,6 +475,14 @@ func (db *sqlite3) Filters() []core.Filter {
|
||||
return []core.Filter{&core.IdFilter{}}
|
||||
}
|
||||
|
||||
func (db *sqlite3) RetryOnError(err error) bool {
|
||||
var sqlError sqlite.Error
|
||||
if errors.As(err, &sqlError) && (sqlError.Code == sqlite.ErrLocked || sqlError.Code == sqlite.ErrBusy) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type sqlite3Driver struct {
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
||||
|
||||
runtime.SetFinalizer(engine, close)
|
||||
|
||||
if ext, ok := dialect.(DialectExt); ok {
|
||||
if ext, ok := dialect.(DialectWithSequenceGenerator); ok {
|
||||
engine.sequenceGenerator, err = ext.CreateSequenceGenerator(db.DB)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create sequence generator: %w", err)
|
||||
@@ -138,9 +138,14 @@ type SequenceGenerator interface {
|
||||
Reset()
|
||||
}
|
||||
|
||||
type DialectExt interface {
|
||||
type DialectWithSequenceGenerator interface {
|
||||
core.Dialect
|
||||
|
||||
// CreateSequenceGenerator returns optional generator used to create AUTOINCREMENT ids for inserts.
|
||||
CreateSequenceGenerator(db *sql.DB) (SequenceGenerator, error)
|
||||
}
|
||||
|
||||
type DialectWithRetryableErrors interface {
|
||||
core.Dialect
|
||||
RetryOnError(err error) bool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user