package main
import (
"context"
"database/sql"
)
func WithTx(ctx context.Context, db *sql.DB, fn func(*sql.Tx) error) (err error) {
tx, err := db.BeginTx(ctx, nil)
if err != nil { return err }
defer func() {
if p := recover(); p != nil {
_ = tx.Rollback()
panic(p) // re-panic after rollback
} else if err != nil {
_ = tx.Rollback()
} else {
err = tx.Commit()
}
}()
return fn(tx)
}
// Usage
//
// err := WithTx(ctx, db, func(tx *sql.Tx) error {
// if _, err := tx.ExecContext(ctx, "INSERT INTO orders ..."); err != nil {
// return err // auto-rollback
// }
// _, err := tx.ExecContext(ctx, "UPDATE inventory SET qty = qty - 1 WHERE id = ?", 42)
// return err
// })
Create a free account and build your private vault. Share publicly whenever you want.