x/database/transactor.go
2025-03-10 22:59:03 -07:00

30 lines
659 B
Go

package database
import (
"context"
"database/sql"
"fmt"
)
// WithinTransaction is a functional equivalent of the Transactor interface created by Thibaut Rousseau's
// https://blog.thibaut-rousseau.com/blog/sql-transactions-in-go-the-good-way/
func WithinTransaction(f Func) Func {
return func(ctx context.Context, db *sql.DB) error {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("failed to begin transaction: %w", err)
}
if err := f(ctx, db); err != nil {
_ = tx.Rollback()
return err
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit transaction: %w", err)
}
return nil
}
}