Improve transaction handling in github.com/titpetric/factory
This is an ugly/temp update of vendored github.com/titpetric/factory. It fixes: - invalid savepoint rollback SQL syntax - err handling on rollback calls - inc. number of tries in case of a (dead)lock (from 3 to 64) - better backoff algo for sleep between retries
This commit is contained in:
parent
1397e8eeb5
commit
f79e210407
27
vendor/github.com/titpetric/factory/database.go
generated
vendored
27
vendor/github.com/titpetric/factory/database.go
generated
vendored
@ -235,6 +235,10 @@ func (r *DB) Begin() (err error) {
|
||||
|
||||
// Transaction will create a transaction and invoke a callback
|
||||
func (r *DB) Transaction(callback func() error) (err error) {
|
||||
// Max tries in case of a (dead)lock
|
||||
// @todo should be configurable
|
||||
const MAX_TRIES = 64
|
||||
|
||||
var try int
|
||||
|
||||
// Perform transaction statements
|
||||
@ -250,7 +254,8 @@ func (r *DB) Transaction(callback func() error) (err error) {
|
||||
}
|
||||
|
||||
try++
|
||||
if try > 3 {
|
||||
//
|
||||
if try > MAX_TRIES {
|
||||
r.logger.Log(r.ctx, fmt.Sprintf("Retried transaction %d times, aborting", try-1))
|
||||
break
|
||||
}
|
||||
@ -267,8 +272,15 @@ func (r *DB) Transaction(callback func() error) (err error) {
|
||||
// - 1213: deadlock found
|
||||
if cause.Number == 1205 || cause.Number == 1213 {
|
||||
r.logger.Log(r.ctx, "Retrying transaction", logger.NewField("try", try), logger.NewField("cause", cause))
|
||||
r.Rollback()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
err = r.Rollback()
|
||||
if err != nil {
|
||||
r.logger.Log(r.ctx, "failed to rollback transaction", logger.NewField("err", err))
|
||||
return err
|
||||
}
|
||||
|
||||
// raise time to sleep on each try
|
||||
time.Sleep(time.Millisecond * time.Duration(try * 50))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -277,7 +289,12 @@ func (r *DB) Transaction(callback func() error) (err error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
r.Rollback()
|
||||
rerr := r.Rollback()
|
||||
if rerr != nil {
|
||||
r.logger.Log(r.ctx, "failed to rollback transaction", logger.NewField("err", rerr))
|
||||
return rerr
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
return r.Commit()
|
||||
@ -318,7 +335,7 @@ func (r *DB) Rollback() (err error) {
|
||||
r.inTx = 0
|
||||
return nil
|
||||
}
|
||||
if _, err = r.Exec(fmt.Sprintf("ROLLBACK SAVEPOINT sp_%d", r.inTx-1)); err != nil {
|
||||
if _, err = r.Exec(fmt.Sprintf("ROLLBACK TO SAVEPOINT sp_%d", r.inTx-1)); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
r.inTx--
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user