30 lines
659 B
Go
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
|
|
}
|
|
}
|