stash/pkg/models/transaction.go

83 lines
1.7 KiB
Go

package models
import (
"context"
"github.com/stashapp/stash/pkg/logger"
)
type Transaction interface {
Begin() error
Rollback() error
Commit() error
Repository() Repository
}
type ReadTransaction interface {
Begin() error
Rollback() error
Commit() error
Repository() ReaderRepository
}
type TransactionManager interface {
WithTxn(ctx context.Context, fn func(r Repository) error) error
WithReadTxn(ctx context.Context, fn func(r ReaderRepository) error) error
}
func WithTxn(txn Transaction, fn func(r Repository) error) error {
err := txn.Begin()
if err != nil {
return err
}
defer func() {
if p := recover(); p != nil {
// a panic occurred, rollback and repanic
if err := txn.Rollback(); err != nil {
logger.Warnf("error while trying to roll back transaction: %v", err)
}
panic(p)
} else if err != nil {
// something went wrong, rollback
if err := txn.Rollback(); err != nil {
logger.Warnf("error while trying to roll back transaction: %v", err)
}
} else {
// all good, commit
err = txn.Commit()
}
}()
err = fn(txn.Repository())
return err
}
func WithROTxn(txn ReadTransaction, fn func(r ReaderRepository) error) error {
err := txn.Begin()
if err != nil {
return err
}
defer func() {
if p := recover(); p != nil {
// a panic occurred, rollback and repanic
if err := txn.Rollback(); err != nil {
logger.Warnf("error while trying to roll back RO transaction: %v", err)
}
panic(p)
} else if err != nil {
// something went wrong, rollback
if err := txn.Rollback(); err != nil {
logger.Warnf("error while trying to roll back RO transaction: %v", err)
}
} else {
// all good, commit
err = txn.Commit()
}
}()
err = fn(txn.Repository())
return err
}