voidwalker/db/tx.go
2023-05-30 18:17:46 +02:00

46 lines
1.2 KiB
Go

package db
import (
"context"
"github.com/lbryio/lbry.go/v2/extras/errors"
log "github.com/sirupsen/logrus"
"github.com/volatiletech/sqlboiler/v4/boil"
)
// TxFunc is a function that can be wrapped in a transaction
type TxFunc func(tx boil.Transactor) error
// WithTx wraps a function in an sql transaction. the transaction is committed if there's no error, or rolled back if there is one.
// if `currentTx` is nil, a new transaction is started. otherwise currentTx is used as the transaction
func WithTx(currentTx boil.Transactor, f TxFunc) (err error) {
var tx boil.Transactor
if currentTx != nil {
tx = currentTx
} else {
tx, err = boil.BeginTx(context.Background(), nil)
if err != nil {
return err
}
defer func() {
if p := recover(); p != nil {
rollbackErr := tx.Rollback()
if rollbackErr != nil {
log.Errorln(errors.Prefix("rollback failed after tx error", rollbackErr))
}
panic(p)
} else if err != nil {
rollbackErr := tx.Rollback()
if rollbackErr != nil {
log.Errorln(errors.Prefix("rollback failed after tx error", rollbackErr))
}
} else {
err = errors.Err(tx.Commit())
}
}()
}
return f(tx)
}